Объединение при выборе отдельного в MySQL переупорядочивает по объединенной таблице

#mysql #join #sql-order-by

#mysql #Присоединиться #sql-order-by

Вопрос:

Я искал ответ на этот вопрос, но я его не нахожу. У меня есть сайт со статьями, хранящимися в таблице статей, и авторами в таблице пользователей. Я хотел получить список авторов, упорядоченных по тому, как недавно они написали статью.

Это дает мне идентификаторы пользователей:

 SELECT distinct a.user_id 
FROM `article` as a 
ORDER BY a.id desc
  

Проблема в том, что как только я пытаюсь ввести имена путем объединения, порядок меняется так, что это по идентификатору пользователя. Я пробовал это:

 SELECT distinct a.user_id, u.name 
FROM `article` as a 
LEFT JOIN user as u on u.id  = a.user_id 
ORDER BY a.id desc, u.id desc
  

и

 SELECT distinct a.user_id, u.name 
FROM `article` as a 
LEFT JOIN user as u on u.id  = a.user_id 
ORDER BY u.id desc, a.id desc
  

но оба изменяют порядок имен. Я, очевидно, делаю что-то глупое, но что?

Комментарии:

1. Вы хотите отсортировать по тому, как недавно они написали статью, но сортируете по полю ID. Почему не поле «ArticleWrittenDate» или что-то в этом роде?

2. Вы, конечно, правы: существует поле writen_on datetime, но между опубликованной датой и полем id никогда не бывает большого расхождения, и я пытался упростить ситуацию для простоты, и новый ответ, который я получил, может быть легко адаптирован в любом случае. 🙂

Ответ №1:

Тот факт, что DISTINCT работает с ORDER BY в вашем первом примере, является случайностью, а не стандартным SQL. Вам нужно что-то вроде этого:

 SELECT a.user_id, u.name 
  FROM article a 
  LEFT JOIN user u ON u.id = a.user_id 
  GROUP BY a.user_id
  ORDER BY MAX(a.id) desc
  

Комментарии:

1. Большое спасибо! Это определенно работает, и я это тоже понимаю. 🙂

Ответ №2:

попробуйте это

 SELECT a.user_id, u.name 
FROM `article` a 
LEFT JOIN user u on u.id = a.user_id 
GROUP BY a.user_id
ORDER BY a.id desc
  

Ответ №3:

Ваш ORDER BY сортирует строки либо по идентификатору пользователя, либо по идентификатору статьи (в зависимости от примера).

Если вы хотите надежную сортировку по имени, затем включите u.name поле в ПОРЯДКЕ ПО полям.

Ответ №4:

это синтаксис postgres, но вы можете легко перевести его в mysql

 select u.*, q.last_article_id 
   from user u
      inner join (
        select a.user_id, max(a.id) as last_article_id
           from article a
           group by a.user_id
      ) q
      on u.id = a.q.id
   order by q.last_article_id desc
  

Ответ №5:

Должно работать что-то вроде следующего:

 select users.id, articles.id, max(articles.created_at) as recent_date
  from users
  left join articles on users.id = articles.user_id
  group by articles.id
  order by recent_date
  

Не уверен, как именно называются ваши поля и все такое, но это должно указать вам правильное направление.

У вас есть много ответов на выбор… Я считаю, что ключом к тому, о чем вы спрашиваете, является использование агрегатной функции MAX() http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_max