#mysql #sql #sql-order-by #inner-join
#mysql #sql #sql-order-by #внутреннее объединение
Вопрос:
Структура таблицы из comments
:
id | user_id | cmt_id | slug
1 | 565 | 5 | home
2 | 324 | 6 | home
3 | 71 | 7 | home
4 | 408 | 1 | about
Структура таблицы из 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
Как вы можете видеть в таблице cmt_likes
, на home
странице комментарий от пользователя 324
имеет 3 лайка, а комментарий от пользователя 71
имеет 2 лайка (я использую количество строк, которые имеют одинаковое значение cmt_id
и slug
для подсчета лайков).
Это мой текущий sql, это только для отображения комментариев:
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
Но я хочу ORDER BY
количество лайков.
итак, я попытался:
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
Но этот sql возвращает только те строки, которые имеют «лайки». Если вы посмотрите на мои таблицы, вы увидите, что комментарий от пользователя 565
не имеет лайков, поэтому эта строка не возвращается в приведенном выше sql.
Это мой текущий результат с приведенным выше sql:
324
71
И это то, чего я ожидал:
324
71
565
Ответ №1:
Тебе нужны left join
s. Я также рекомендую использовать псевдонимы таблиц:
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
Однако, я думаю, вам также нужна агрегация перед 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
Комментарии:
1. Действительно, мне нужно было изменить только
INNER JOIN
наLEFT JOIN
в моем втором sql.