GROUP BY - выполнить сортировку внутри группы

При выполнении группировки

GROUP BY

Каким образом указывается сортировка? В данный момент, группируется и берется первая строка. А что если необходима последняя строка в группе?

id list  name
1   0    name1 
2   1    name2
3   3    name3
4   1    name4
5   3    name5
6   0    name6

На выходе необходимо получить

id list  name
6   0    name6
5   3    name5
4   1    name4
1   0    name1

SELECT * FROM news GROUP BY IF(list=0, -id, list) HAVING MAX(id) ORDER BY id DESC

Ответы (1 шт):

Автор решения: Akina

Рассмотрим ту же проблему на более простом примере.

Имеется таблица:

CREATE TABLE test (a INT, b INT);
INSERT INTO test VALUES (1,1), (1,2);

Выполняется запрос:

SELECT a, b
FROM test
GROUP BY a;

Мы требуем группировку по a. То есть в результате мы должны получить одну запись для каждого значения этого поля в исходной таблице, сколько бы раз оно там не присутствовало. На показанных данных в таблице такое значение одно - единица, и встречается оно дважды - то есть на выходе получится одна запись, и в поле a будет единица.

Но что будет в результате поле b? Исходных записей - две, там значения один и два. Что вернуть? какое из этих значений выбрать? и почему? текст запроса на эти вопросы ответов не даёт... А сервер - он не будет проявлять инициативу и выбирать одно из имеющихся значений "от фонаря". Он просто сообщит, что условие выбора недоопределено. И сообщит это, выдав сообщение об ошибке.

Для того, чтобы запрос был корректен, любое поле выходного набора, которое не указано в выражении группировки, должно быть аргументом агрегатной функции. Например, так:

SELECT a, MAX(b) AS b
FROM test
GROUP BY a;

В этом случае у сервера нет никакой неопределённости. Ему чётко сказано, что в поле b надо поместить максимальное из имеющихся значений. И он из имеющихся значений со спокойной душой вернёт двойку.


Кроме указанной ошибки, запрос в вопросе ещё содержит и логическую избыточность. В нём используется условие пост-отбора HAVING MAX(id). Оно будет истинно, если значение MAX(id) будет не ноль и не NULL. А поскольку (ну во всяком случае чисто визуально) все значения в поле id больше нуля и не NULL, то все результирующие записи будут в этом условии давать истину. То есть это условие вообще можно удалить - оно не влияет на результат.

→ Ссылка