MySQL / 6. Сортировка результатов запроса

Сортировка результатов выражения

Задача
Вы хотите упорядочить результат запроса на основе вычисления значений некоторых выражений над столбцами.

Решение
Поместите выражение, вычисляющее значение, в инструкцию ORDER BY. Если вы работаете со старой версией MySQL, не поддерживающей выражения в ORDER BY, используйте обходной маневр.

Обсуждение
Один из столбцов таблицы mail содержит величину сообщения в байтах:

mysql> SELECT * FROM mail;

+--------------------------+---------+---------+----------+---------+---------+
| t                                  | srcuser | srchost | dstuser | dsthost | size      
+--------------------------+---------+---------+----------+---------+---------+
| 2001-05-11 10:15:08 | barb     | saturn  | tricia      | mars     | 58274   |
| 2001-05-12 12:48:13 | tricia     | mars    | gene      | venus   | 194925 |
| 2001-05-12 15:02:49 | phil       | mars     | phil        | saturn  | 1048     |
| 2001-05-13 13:59:18 | barb     | saturn  | tricia      | venus   | 271       |

... Предположим, что вы хотите извлекать только «большие» сообщения (например, превышающие 50 000 байт), но при этом выводить и упорядочивать их в терминах килобайтов, а не байтов. Вы можете применить для сортировки результатов выражения инструкцию ORDER BY, если это допускает ваша версия MySQL.

Выражения в инструкции ORDER BY не разрешены в версиях MySQL, предшествующих 3.23.2. Чтобы обойти это ограничение, укажите выражение в списке столбцов вывода и сошлитесь на него либо позиционно, либо используя псевдоним:

mysql> SELECT t, srcuser, FLOOR((size+1023)/1024) -> FROM mail WHERE size > 50000
-> ORDER BY 3;

+--------------------------+---------+--------------------------------+
| t                                  | srcuser | FLOOR((size+1023)/1024) |
+--------------------------+---------+--------------------------------+
| 2001-05-11 10:15:08 | barb     | 57                                        |
| 2001-05-14 14:42:21 | barb     | 96                                        |
| 2001-05-12 12:48:13 | tricia     | 191                                      |
| 2001-05-15 10:25:52 | gene     | 976                                      |
| 2001-05-14 17:03:01 | tricia     | 2339                                    |
+--------------------------+---------+--------------------------------+

mysql> SELECT t, srcuser, FLOOR((size+1023)/1024) AS kilobytes
-> FROM mail WHERE size > 50000
-> ORDER BY kilobytes;

+--------------------------+---------+-----------+
| t                                  | srcuser | kilobytes |
+--------------------------+---------+-----------+
| 2001-05-11 10:15:08 | barb      | 57          |
| 2001-05-14 14:42:21 | barb      | 96          |
| 2001-05-12 12:48:13 | tricia      | 191       |
| 2001-05-15 10:25:52 | gene      | 976       |
| 2001-05-14 17:03:01 | tricia      | 2339     |
+--------------------------+----------+----------+

Такой способ будет работать и для версий MySQL 3.23.2 и выше, но в них появляется дополнительная возможность размещения выражения непосредственно в инструкции ORDER BY:

mysql> SELECT t, srcuser, FLOOR((size+1023)/1024)
-> FROM mail WHERE size > 50000
-> ORDER BY FLOOR((size+1023)/1024);

+--------------------------+---------+---------------------------------+
| t                                   | srcuser | FLOOR((size+1023)/1024) |
+--------------------------+---------+---------------------------------+
| 2001-05-11 10:15:08 | barb      | 57                                        |
| 2001-05-14 14:42:21 | barb      | 96                                        |
| 2001-05-12 12:48:13 | tricia     | 191                                       |
| 2001-05-15 10:25:52 | gene     | 976                                       |
| 2001-05-14 17:03:01 | tricia     | 2339                                     |
+--------------------------+---------+----------------------------------+

Однако даже если вы помещаете выражение в инструкцию ORDER BY, есть по крайней мере две причины для того, чтобы использовать для него псевдоним:

• Легче написать инструкцию ORDER BY, используя псевдоним, чем заново вводя выражение (которое может быть весьма громоздким).

• Псевдоним может быть удобен при выводе – столбец получает понятное и осмысленное название.

Такое же ограничение накладывается на выражения в инструкции GROUP BY), и обходить его следует так же. Не забудьтеоб этом, если ваша версия MySQL старше, чем 3.23.2. Многие запросы далее в книге используют выражения в инструкциях ORDER BY и GROUP BY. Чтобы они заработали на ранних версиях сервера MySQL, вам придется переписать их, применяя только что изученный прием.

Статьи по MySQL на эту тему:

Размещение некоторых значений в начале или конце упорядоченного списка
Сортировка IP-адресов в числовом порядке
Сортировка в порядке, определенном пользователем
Сортировка значений ENUM
Сортировка и значения NULL