Table structure from comments
:
id | user_id | cmt_id | slug 1 | 565 | 5 | home 2 | 324 | 6 | home 3 | 71 | 7 | home 4 | 408 | 1 | about
Table structure from cmt_likes
:
id | user_id | cmt_id | slug 1 | 324 | 6 | home 2 | 324 | 6 | home 3 | 324 | 6 | home 4 | 71 | 7 | home 5 | 71 | 7 | home
As you can see on the table cmt_likes
, on the home
page the comment from the user 324
have 3 likes, and the comment from the user 71
have 2 likes (i use the number of rows, that have the same cmt_id
and slug
to count the likes).
This is my current sql, this is only for display the comments:
SELECT `comments`.`user_id`, `comments`.`cmt`, `comments`.`cmt_id`, `comments`.`slug`, `users`.`username` FROM `comments` INNER JOIN `users` ON `comments`.`user_id` = `users`.`user_id` WHERE `comments`.`slug` = :slug ORDER BY `comments`.`id` DESC
But i want to ORDER BY
the number of likes.
so i tried:
SELECT `comments`.`user_id`, `comments`.`cmt`, `comments`.`cmt_id`, `comments`.`slug`, `cmt_likes`.`cmt_id`, `users`.`username` FROM `comments` INNER JOIN `users` ON `comments`.`user_id` = `users`.`user_id` INNER JOIN `cmt_likes` ON `comments`.`cmt_id` = `cmt_likes`.`cmt_id` WHERE `comments`.`slug` = :slug GROUP BY `cmt_likes`.`cmt_id` ORDER BY `cmt_likes`.`cmt_id` DESC
But this sql only return the rows that have ‘likes’. If you look at my tables you will see that the comment from the user 565
don’t have likes, so this row is not returning in the above sql.
This is my current result with the above sql:
324 71
And this is what i expected:
324 71 565
Advertisement
Answer
You need left join
s. I also recommend table aliases:
SELECT c.user_id, c.cmt, c.cmt_id, c.slug, c.cmt_id, u.username FROM comments c LEFT JOIN users u ON c.user_user = u.user_id LEFT JOIN cmt_likes cl ON c.cmt_id = cl.cmt_id WHERE c.slug = :slug GROUP BY c.user_id, c.cmt, c.cmt_id, c.slug, c.cmt_id, u.username ORDER BY cl.cmt_id DESC
However, I think you also need aggregation before the JOIN
:
SELECT c.user_id, c.cmt, c.cmt_id, c.slug, c.cmt_id, u.username FROM comments c LEFT JOIN users u ON c.user_user = u.user_id LEFT JOIN (SELECT cl.cmt_id, COUNT(*) as cnt FROM cmt_likes cl GROUP BY cl.cmt_id ) cl ON c.cmt_id = cl.cmt_id WHERE c.slug = :slug GROUP BY c.user_id, c.cmt, c.cmt_id, c.slug, c.cmt_id, u.username ORDER BY cl.cmt_id DESC