Как УПОРЯДОЧИТЬ ПО столбцу из ВНУТРЕННЕГО СОЕДИНЕНИЯ

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