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 шт):
Рассмотрим ту же проблему на более простом примере.
Имеется таблица:
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, то все результирующие записи будут в этом условии давать истину. То есть это условие вообще можно удалить - оно не влияет на результат.