2010-09-07 1 views
2

У меня есть запрос:MySQL LEFT JOIN по возрастанию

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 

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

+1

Как вы/мы знаем, какие медали является последним один? –

+0

вопрос в том, почему он получает его в порядке возрастания – Wiika

+0

Ваши запросы заказов по значениям 'reply.id' в порядке возрастания - мы ничего не знаем о вашей структуре данных или таблиц, но ваш заключительный оператор включает в себя« захватить первую медаль, которая пользователь получил - мне нужно получить последний. " В контексте, это означает, что вы хотите получить последнюю медаль ... –

ответ

0

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

0

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

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

этот запрос будет хорошим выбором для меня прямо сейчас, я присоединяюсь к более чем 3 таблицам, я попытался (SELECT id FROM medals WHERE userid = user. id ORDER BY id DESC LIMI 1) AS m_id И затем присоединиться к ON medal.id = m_id ut слишком медленно – Wiika

+0

Да, вы не хотите этого делать, он будет запускать запросы «N + 1». Идя по этому маршруту, вы просто запускаете два запроса, один из временных таблиц ... это не идеально, но я думаю, что это лучший вариант. – wuputah

1

Тот факт, что вы видите первую запись в каждой группе является случайным. Выбор неагрегатного столбца, не относящегося к группе, в запросе 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

 Смежные вопросы

  • Нет связанных вопросов^_^