SQL: Как сохранить порядок строк с помощью DISTINCT? - PullRequest
5 голосов
/ 11 августа 2011

Следующий запрос SQL:

SELECT messages.id, messages.created_at, comments.created_at FROM messages
LEFT JOIN comments ON comments.message_id = messages.id 
WHERE (messages.id IN (429,443)) 
ORDER BY GREATEST(messages.created_at, comments.created_at) DESC

возвращается:

 id         messages.created_at     comments.created_at
--------------------------------------------------------
 443                2                       5
 429                1                       4
 443                2                       3

 (I replaced dates with numbers for readability)

Чтобы получить каждый id только один раз, я добавил DISTINCT:

SELECT DISTINCT messages.id FROM messages
LEFT JOIN comments ON comments.message_id = messages.id 
WHERE (messages.id IN (429,443)) 
ORDER BY GREATEST(messages.created_at, comments.created_at) DESC

Но, в результате значения id изменили порядок:

id
---
429
443

В чем может быть причина этого?

Как я могу сохранить заказ?

1 Ответ

14 голосов
/ 11 августа 2011

ключевое слово distinct делает то, что должно, возвращает одну строку с заданным значением столбца.Distinct не позволяет вам указать , какая такая строка будет возвращена, и из исходного запроса ясно, что такой порядок разрешен (есть строка с идентификатором 443, которая следует за строкой с идентификатором 429).

Чтобы получить контроль над тем, какие строки будут возвращены, необходимо переформулировать запрос.Типичное решение, которое я приму, это использовать group by, выбирая столбец группы и нужную строку из каждой группы, что-то с эффектом

SELECT message.id, MAX(message.created_at) FROM message GROUP BY message.id;

Если мне нужно сделать больше, я 'Я буду использовать этот тип запроса в качестве подвыбора в большем запросе, возможно, присоединяясь к полю id, чтобы получить больше полей из предпочтительной строки, или упорядочив запрос определенным образом.

...