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
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