MySQL оставил присоединиться по возрастанию - PullRequest
2 голосов
/ 07 сентября 2010

У меня есть запрос:

   SELECT reply.id,
          reply.message,
          reply.userid,
          reply.date,
          medal.id,
          medal.url,
          medal.name,
          user.id,
          user.name AS username
     FROM posts AS reply
LEFT JOIN users AS user ON reply.userid = user.id
LEFT JOIN medals AS medal ON medal.userid = user.id
 GROUP BY reply.id
 ORDER BY reply.id ASC

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

Ответы [ 3 ]

1 голос
/ 07 сентября 2010

Тот факт, что вы видите первую запись в группе, является случайным.Выбор неагрегированного столбца, не являющегося уникальным для группы, в запросе GROUP BY приводит к выбору неопределенной записи.

Более подробное объяснение читайте: http://dev.mysql.com/tech-resources/articles/debunking-group-by-myths.html.

Один правильный путьчтобы сделать то, что вы делаете, используйте подзапрос, в котором вы выбираете максимальную дату медали для желаемой группы.

Этот подход описан здесь: http://dev.mysql.com/doc/refman/5.6/en/example-maximum-column-group-row.html

0 голосов
/ 07 сентября 2010

Самое простое решение - сделать это:

ORDER BY reply.id ASC, medal.id DESC

И удалить ваше заявление GROUP BY.

Вы можете отфильтровать сообщения / пользователей, у которых впоследствии есть несколько медалей (пропустить строки, содержащие ненужные медали).

Следующий вариант - выбрать MAX(medal.id) в подзапросе, а затем присоединиться к нему. Это грязно, но выполнимо. Вот общая идея (вам, вероятно, придется переименовать несколько псевдонимов таблиц, поскольку они используются более одного раза):

SELECT *,
       medal.url,
       medal.name
FROM
(
   SELECT reply.id,
          reply.message,
          reply.userid,
          reply.date,
          MAX(medal.id) AS medal_id,
          user.id,
          user.name AS username
     FROM posts AS reply
LEFT JOIN users AS user ON reply.userid = user.id
LEFT JOIN medals AS medal ON medal.userid = user.id
 GROUP BY reply.id
 ORDER BY reply.id ASC
)
AS t
LEFT JOIN medals AS medal ON medal.id = t.medal_id
0 голосов
/ 07 сентября 2010

Вы могли бы сделать подзапрос или временную таблицу для медалей, вместо того, чтобы присоединиться непосредственно к медалям.Временной таблицей будет таблица медалей, но отсортированная DESC.Подзапросом будет LEFT JOIN (выберите id, url, name из списка медалей по desc), но я чувствую, что это будет очень медленно и не лучшим вариантом.

...