Сортировка перед группировкой в MySQL

Когда мы пытаемся выдрать что-то из БД — то сначала указываем GROUP BY, а потом уже ORDER BY. Таким образом в запросе у нас сначала выполняется группировка по указанному столбцу и только потом сортируется. Это не всегда удобно, но синтаксис MySQL не позволяет сделать сначала ORDER BY, а потом уже GROUP BY. 

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

SELECT * FROM ( SELECT * FROM `table` ORDER BY `anything` DESC) AS orderedTable GROUP BY `anything_else`;

Сначала у нас выберутся все поля из таблицы `table` и сформируется таблица orderedTable (обратите внимание, что указание альяса для вложенного запроса обязательно, иначе получите ошибку ERROR 1248 (42000): Every derived table must have its own alias). А потом уже из неё выберуться все поля и сгруппируются.


Читайте также:

комментариев 13

  1. Urich:

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

    • Есть записи в таблице БЛОГ. Она связана с ПОЛЬЗОВАТЕЛИ. Надо вывести все записи авторов, чтобы они не повторялись (авторы) упорядоченные по дате.Чтобы не повторялись — через GROUP BY. Если группировать до сортировки — то даты левые.

      • Подвальный кот:

        Сортируй-не сортируй, все равно получишь ерунду.
        Нужно, чтобы были даты последнего сообщения каждого автора? Или первого?

        SELECT MAX(time) AS last_message_time, message, user FROM messages GROUP BY user ORDER BY last_message_time;

        А для первого MIN, само собой.

        • Подвальный кот:

          Хотя нет, так тоже ерунда получится. Даты верные, а вот сообщения не те будут.

          SELECT user, messages.time, message FROM messages JOIN (SELECT user, MAX(time) AS time FROM messages GROUP BY user) AS umtime USING(user) where messages.time = umtime.time ORDER BY time;

          (Возможно, немного перемудрил, но суть такова :))

      • vasya:

        Ваш «обходной путь» будет работать не всегда, а в последних версиях так точно не сработает.

        • beowulf13th:

          Давайте не будем пиарить свой бложик ;) Данный способ у меня работает на последней версии MySQL.

          • vasya:

            Тяжелый случай. Последняя это какая?
            Вот вам пример

            P.S. Если пишите, то хоть исправляйте явный бред, вам ещё в первом коменте уазали на абсурдность постановки вопроса.

            • beowulf13th:

              Если MariaDB так делает — это проблема MariaDB.
              Версия MySQL — 5.6.15

              • vasya:

                Скорее это проблемы MySQL, возможности которого отстают от MariaDB. И ваша, так как
                1. для выполнения простой задачи создаете копию исходной таблицы
                2. придется искать ошибку в приложении, когда MySQL станет оптимизировать такой запрос
                3. кстати, в вашей версии у вас есть возможность получить неправильный результат при использовании этого метода в сложном запросе

    • Подвальный кот:

      Именно. Никакая сортировка таблицы не заставит группировку обрабатывать строки в том же порядке. Сортировка же работает только с представлением данных для пользователя, внутри структура таблицы вроде бы меняться не должна. И GROUP BY получает по сути одну и ту же таблицу, независимо от того, была она предварительно отсортирована или нет.

  2. Иван:

    Спасибо, просто и понятно. и помогло! :)

  3. Пётр:

    Не делайте так никогда! Результат может изменится как только будет перестроен индекс или произойдут обновления версии СУБД или поменяется фаза луны! Не пользуйтесь недокументированными способами! Вот аж 5 способов как это можно сделать.

  4. Евгений:

    О ты мой спаситель! Уже битый час бью с этой ошибкой и тут твоя статья! Спасибо, выручило!

Добавить комментарий для beowulf13th Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *