MySQL get title from parentid with two tables - php

I will try to explain much as possible. here is my query..
SELECT * FROM mm_star_ratings s
JOIN mm_posts p ON s.post_id = p.postid
WHERE p.type='B'
ORDER BY s.rating DESC LIMIT 5
type='B' is the main post and type='C' is the reply on that post. There is a parentid column in mm_posts to set main post (B) id for C. Do I want to get the title from mm_posts if type='C' is there anyway?
The challenge for me is to get it work with my rating table where post_id is set for both B and C

You can use Following query,
SELECT s.*,p.*, IF(p.type='C',pp.title,p.title) as title FROM mm_star_ratings s
JOIN mm_posts p ON s.post_id = p.postid Left Join mm_posts pp on pp.postid=p.parent_id
ORDER BY s.rating DESC LIMIT 5

Related

left join alle topics only last post order by sticky and last post DESC

i am trying to get all topics based on a forum ID.
Those topics need to be ordered by sticky first and then by last post date secondly.
I have this query, working almost fine but it doesn't order the topics in the way i want.
SELECT
forum_posts.posted_by,
forum_posts.posted,
forum_topics.id,
forum_topics.subject,
forum_topics.sticky,
forum_topics.closed
FROM
forum_posts
LEFT JOIN
forum_topics
ON
forum_topics.id=forum_posts.topic_id
WHERE forum_topics.forum_id=$forumdata->id
GROUP BY forum_topics.id
ORDER BY forum_posts.posted DESC
If I read your question correctly, then you only need to make a slight change to the ORDER BY clause:
ORDER BY
forum_topics.sticky, -- just add this
forum_posts.posted DESC;
However, as you are selecting non aggregate columns, my hunch is that you should really be using a subquery to figure out the latest post:
SELECT
ft.*, fp1.*
FROM forum_posts fp1
INNER JOIN
(
SELECT topic_id, MAX(posted) AS max_posted
FROM forum_posts
GROUP BY topic_id
) fp2
ON fp1.topic_id = fp2.topic_id AND
fp1.posted = fp2.max_posted
LEFT JOIN forum_topics ft
ON fp1.id = ft.topic_id
ORDER BY
ft.sticky;
if you need sticky first an then post then you need order by orum_topics.sticky, forum_posts.posted eg:
SELECT
forum_posts.posted_by,
forum_posts.posted,
forum_topics.id,
forum_topics.subject,
forum_topics.sticky,
forum_topics.closed
FROM
forum_posts
LEFT JOIN
forum_topics
ON
forum_topics.id=forum_posts.topic_id
WHERE forum_topics.forum_id=$forumdata->id
GROUP BY forum_topics.id
ORDER BY forum_topics.sticky DESC, forum_posts.posted DESC

Finding username of the last post in mysql table joining 3 tables

I know I am doing this qry wrong - its taking over 10secs for the results to come back w/ only 3000 rows of data...
I have 3 tables:
users
id
username
DATA:
1|tom
2|dick
3|harry
posts
id
id_users
DATA:
1|1
2|1
3|1
4|2
5|2
6|3
cronjobs
id
id_post
id_wall
DATA: id|id_post|id_wall
1|1|1
2|1|2
3|1|3
4|1|4
5|1|5
6|2|5
7|4|3
8|6|3
9|4|4
A user will make a post
That post will be put on one or more walls and stored in the cronjobs table.
The id on cronjobs is auto increment.
I need to get the username and last post on each wall.
In the above example
Dick was the last person to post on wall 4 with post 4
Harry was the last person to post on wall 3 with post 6
Tom was the last person to post on wall 5 with post 2
Tom was the last person to post on wall 2 with post 1
Tom was the last person to post on wall 1 with post 1
Here is the qry im currently using, I know using the IN clause with the select inside it, is killing this....
SELECT
c.id,
c.id_post,
c.id_wall AS id_wall,
p.id_users AS user_id,
u.NAME AS username
FROM
cronjobs c,
posts p,
users u
WHERE c.id IN
(SELECT MAX(id)
FROM
cronjobs
GROUP BY id_wall)
AND c.id_post = p.id
AND p.id_users = u.id
ORDER BY c.id
Any help is appreciated!
Try this
SELECT
c.id,
c.id_post,
c.id_wall AS id_wall,
p.id_users AS user_id,
u.NAME AS username
FROM
cronjobs c,
posts p,
users u ,
(SELECT MAX(id) as id
FROM
cronjobs
GROUP BY id_wall) table_id
where c.id_post = p.id
AND p.id_users = u.id
and table_id.id =c.id
ORDER BY c.id
You can use join instead of a subquery in where clause, subquery in join part will be executed once while subquery in where clause will be executed for all the resultant rows this query will perform much better than yours, also index your columns that appears in on() part
SELECT
c.id,
c.id_post,
c.id_wall AS id_wall,
p.id_users AS user_id,
u.username AS username
FROM
cronjobs c
join (SELECT MAX(id) id ,id_wall
FROM cronjobs
GROUP BY id_wall) c1 on c.id = c1.id and c.id_wall = c1.id_wall
join posts p on c.id_post = p.id
join users u on p.id_users = u.id
ORDER BY c.id
DEMO

PHP: 2 tables - Maximum id2

I want to get all id with the max id2 value.
I tried just to get the max id2 but then it will looks for the overall maximum value of id2 inside the table , but i want to get all maxiums of id.
So I got 2 tables - table news and table topics.
Everytime I create a news there will automaticly create a topic. Now I want to show all news - and the current number of replies. So first step - topicid = id.
and every topic got id and id2.
id is the topic id
and id2 is the reply id
so if i got topic (a) with 4 comments it would look like
(id(1),id2(1))
(id(1),id2(2))
(id(1),id2(3))
(id(1),id2(4))
now a new topic (b) with 6 comments
(id(2),id2(1))
(id(2),id2(2))
(id(2),id2(3))
(id(2),id2(4))
(id(2),id2(5))
(id(2),id2(6))
so i want to get ((id(1),id2(4)) and (id(2),id2(6)))
<?php
$news = "SELECT n.titel,n.datum,n.typ_news,n.news,n.verfasser,n.time,n.topicid,
t.id, t.id2 FROM news n LEFT JOIN topics t ON t.id = n.topicid
ORDER BY n.id DESC LIMIT 10 ";
$neuenews = mysql_query($news);
while ($dnews = mysql_fetch_array($neuenews))
{
echo " <div style='text-align:center;color:#FFFFFF;font-size: 24px;'> "
.$dnews['titel'].
"a";
}
Ehm this was the solution :
$dn1 = mysql_query('select c.id, c.name, c.description, c.position,c.bild,
(select count(t.id) from topics as t where t.parent=c.id and t.id2=1) as topics,
(select count(t2.id) from topics as t2 where t2.parent=c.id and t2.id2!=1) as replies
from categories as c group by c.id order by c.position asc');
Try this:
SELECT n.titel,n.datum,n.typ_news,n.news,n.verfasser,n.time,n.topicid, t.id, MAX(t.id2) AS id2
FROM news n
LEFT JOIN
topics t
ON t.id = n.topicid
GROUP BY n.topicid
ORDER BY n.id DESC LIMIT 10
It looks like the specified/desired result from the topics table is accomplished by a query like this:
SELECT t.id
, MAX(t.id2) AS max_id2
FROM topics t
GROUP BY t.id
OPTION 1
To get that result joined to rows in news, you could use that query as an inline view in your query in place of the topics table. For example:
SELECT n.titel
, n.datum
, n.typ_news
, n.news
, n.verfasser
, n.time
, n.topicid
, t.id
, t.max_id2
FROM news n
LEFT
JOIN ( SELECT m.id
, MAX(m.id2) AS max_id2
FROM topics m
GROUP BY m.id
) t
ON t.id = n.topicid
ORDER BY n.id DESC LIMIT 10
OPTION 2
If id is UNIQUE (or PRIMARY KEY) in news table, then you may be able to eliminate the inline view, do a join to topics, and do a GROUP BY n.id, something like this:
SELECT n.titel
, n.datum
, n.typ_news
, n.news
, n.verfasser
, n.time
, n.topicid
, t.id
, MAX(t.id2) AS max_id2
FROM news n
LEFT
JOIN topics t
ON t.id = n.topicid
GROUP BY n.id
ORDER BY n.id DESC LIMIT 10
Not clear enough. what are the columns id= 1 id2=1 etc.? Two tables each with 2 columns? No clue.
I'm thinking something on the order but No clue what you actually want.
SELECT `MAX(`id2`) as MAX,`id` FROM `News` WHERE `id2` = `MAX`

MySql inner join takes more than 10 seconds

I have two tables posts and followings
posts (id,userid,post,timestamp) 30 000 rows
and
followings(id_me,userid) 90 000 rows
I want to get lattest 10 posts form posts table based on the people i follow and my posts
SELECT p.*
FROM posts as p INNER JOIN
followings as f
ON (f.id_me=(my user id) AND p.userid=f.userid )
OR
p.userid=(my user id)
ORDER BY id DESC LIMIT 10
But it takes about 10-15 seconds to return. Thanks in advance!
First, remove the filter from the join clause, let the join just correlate the joining tables.
(
SELECT p.*
FROM posts as p
INNER JOIN followings as f ON p.userid=f.userid
where f.id_me=(my user id)
UNION
SELECT p.*
FROM posts as p
where p.userid=(my user id)
)
ORDER BY id DESC LIMIT 10
second, verify your indexes if that ids got no indexes it ill perform a full table scan for each cartesian product of both tables (30k x 90k =~ 3700k pairs being compared)
third, if you don't follow yourself you need a union from post you are following and your posts
Using an OR in SQL is a performance killer, try this:
SELEC p.*
FROM posts as p INNER JOIN
followings as f
ON (f.id_me=(my user id) AND p.userid IN (f.userid,(my user id)))
ORDER BY id DESC LIMIT 10
Do this query using union:
(SELECT p.*
FROM posts p INNER JOIN
followings f
ON (f.id_me=(my user id) AND p.userid=f.userid
)
union
(select p.*
from posts p
where p.userid=(my user id)
)
ORDER BY id DESC
LIMIT 10
If the two conditions never overlap, then use union all instead.
An OR condition like that prevents the query optimizer from making use of indexes. Use a UNION instead:
SELECT *
FROM (SELECT p.*
FROM posts as p
INNER JOIN followings as f
ON f.id_me=(my user id) AND p.userid=f.userid
UNION
SELECT *
FROM posts
WHERE userid = (my user id)) u
ORDER BY id DESC
LIMIT 10
It might be just me but I think your WHERE clause is in an inefficient location:
SELECT
p.*
FROM
posts p
INNER JOIN
followings f
ON p.userid=f.userid
WHERE
MyUserID IN (p.userid, f.id_me)
ORDER BY
id DESC
LIMIT
10
I read in comments that you have the required indexes. The problem is the query. Combining OR with a JOIN confuses the poor and (often) dumb optimizer. The LIMIT 10 should be helpful but the optimizer is not (yet) smart enough to make the best plan.
Try this query:
( SELECT p.*
FROM posts AS p
JOIN followings AS f
ON f.id_me = (my_user_id)
AND p.userid = f.userid
ORDER BY p.id DESC
LIMIT 10
)
UNION ALL
( SELECT p.*
FROM posts AS p
WHERE p.userid = (my_user_id)
ORDER BY p.id DESC
LIMIT 10
) AS x
ORDER BY id DESC
LIMIT 10 ;

I am stuck on one query in mysql

I am stuck on one query in mysql.
I want to fetch most recent comment from the table
the comment should be most recent comment on the blog
the blogs should be latest 3 blogs.
display comment & blog only if their status is Enabled
records should be like this
Table Structure for the table the table blog
blog_id int - primary (auto increment)
blog_title -varchar
blog_desc -varchar
blog_image -varchar
blog_tags -varchar
tot_comments -int
blog_creater -varchar
blog_create_date -datetime
blog_status -enum ('Enable','Disable')
table structure for the table blog_comment
comment_id -int (auto increment)
fk_blog_id -int
comment -varchar
comment_by -varchar
email -varchar
comment_date -datetime
comment_status -enum ('Enable','Disable')
And below is query written by me, but the result I am getting is wrong.
SELECT b.blog_title,b.blog_image, bc.*
FROM blog_comments bc, blog b
WHERE bc.comment_status='Enable'
AND b.blog_status='Enable'
AND b.blog_id=bc.fk_blog_id
GROUP BY bc.fk_blog_id
ORDER BY bc.comment_date DESC
LIMIT 0,3
Output
for this the easy solution will be execute 2 query for your result . first query get blog post result
$db_blog="select blog_id,blog_title from blog where blog_ststus='Enable'";
$que=mysql_query($db_blog);
while($row=mysql_fetch_object($que))
{
echo $row->blog_title;
$db_comment="select comment from blog_comments where fk_blog_id=".$row->blog_id." and comment_status='Enable' order by comment_date desc";
$quec=mysql_query($db_comment);
while($comment=mysql_fetch_object($quec))
{
echo $comment->comment;
}
}
Try this:
SELECT * FROM blog_comments bc, blog b
WHERE `bc.comment_status`='Enable'
AND `b.blog_status`='Enable'
AND `b.blog_id`=bc.fk_blog_id
ORDER BY `bc.comment_date` DESC LIMIT 1;
Try a simpler one:
SELECT * FROM `blog_comment` WHERE 'blog_status'='Enable' AND 'blog_id'='$blogidherefromtitle' ORDER BY 'comment_date' DESC LIMIT1
SELECT b.blog_title,b.blog_image, bc.*
FROM blog b
left join (
Select * from
blog_comments bc
WHERE bc.comment_status='Enable'
GROUP BY bc.fk_blog_id
having max(bc.comment_date) = bc.comment_date
) bcc on b.blog_id=bcc.fk_blog_id
where
b.blog_status='Enable'
ORDER BY b.blog_create_date desc
LIMIT 0,3
Try this one
try
SELECT b.blog_title,b.blog_image, bc.*
FROM blog_comments AS bc, blog AS b
WHERE bc.comment_status='Enable'
AND b.blog_status='Enable'
AND b.blog_id=bc.fk_blog_id
GROUP BY bc.fk_blog_id
ORDER BY bc.comment_date DESC
LIMIT 0,3;
(I'm not 100% sure)
SELECT b.blog_title,b.blog_image, bc.*
FROM blog_comments bc JOIN blog b ON bc.fk_blog_id = b.blog_id
WHERE bc.comment_status='Enable'
AND b.blog_status='Enable'
GROUP BY bc.fk_blog_id
ORDER BY bc.comment_date DESC
LIMIT 0,3
select b.blog_title, b.blog_image, bc.*
from blog b join
(select bc.*
from bc join (select fk_blog_id, max(comment_date) latest_date
from blog_comment
where comment_status = 'Enable'
group by fk_blog_id) latest
on bc.fk_blog_id = latest.fk_blog_id and bc.comment_date = latest_date) c
on b.blog_id = c.fk_blog_id
where b.blog_status = 'Enable'
order by c.comment_date desc
limit 0, 3
The c subquery finds the row with the latest comment for each blog, using the technique in the linked question. This is then joined with the blog table to get the appropriate blog data.
Try this query
SELECT
bc.*
FROM
blog AS b
INNER JOIN (SELECT id , MAX(id) AS MaxID FROM blog) AS bl ON bl.id = b.id
LEFT JOIN blog_comment AS bc ON bc.fk_blog_id = b.id
ORDER BY bc.comment_id DESC
LIMIT 3
EDITS:
SELECT
bc.*
FROM
blog AS b
INNER JOIN (SELECT id , MAX(id) AS MaxID FROM blog GROUP BY id) AS bl ON bl.id = b.id
INNER JOIN (SELECT MAX(id) , fk_blog_id FROM blog_comment GROUP BY id) AS bc ON bc.fk_blog_id = b.id
ORDER BY bc.comment_id DESC
LIMIT 3
This is for 3 latest blogs and latest single comments for each blog
Here using inner join will fetch the latest blog. than join comments and order them with date or id and limit them according to your requirements.

Categories