Размещение некоторых значений в начале или конце упорядоченного списка

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

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

Обсуждение
Если вы хотите, чтобы результирующее множество было упорядочено обычным образом, за исключением того, что в его начало должны быть помещены определенные значения, создайте дополнительный столбец, который содержит 0 для указанных значений и 1 для остальных. Будем использовать прием, который уже применялся для помещения значений NULL в начало упорядоченного списка (рецепт 6.5). Предположим, что вы хотите отсортировать таблицу сообщений mail по отправителям/получателям, при этом первыми должны выводиться сообщения пользователя phil. Сделаем так:

mysql> SELECT t, srcuser, dstuser, size
-> FROM mail
-> ORDER BY IF(srcuser='phil',0,1), srcuser, dstuser;

+--------------------------+---------+----------+---------+
| t | srcuser | dstuser | size |
+--------------------------+---------+----------+---------+
| 2001-05-16 23:04:19 | phil | barb | 10294 |
| 2001-05-12 15:02:49 | phil | phi | 1048 |
| 2001-05-15 08:50:57 | phil | phil | 978 |
| 2001-05-14 11:52:17 | phil | tricia | 5781 |
| 2001-05-17 12:49:23 | phil | tricia | 873 |
| 2001-05-14 14:42:21 | barb | barb | 98151 |
| 2001-05-11 10:15:08 | barb | tricia | 58274 |
| 2001-05-13 13:59:18 | barb | tricia | 271 |
| 2001-05-14 09:31:37 | gene | barb | 2291 |
| 2001-05-16 09:00:28 | gene | barb | 613 |
| 2001-05-15 07:17:48 | gene | gene | 3824 |
| 2001-05-15 17:35:31 | gene | gene | 3856 |
| 2001-05-19 22:21:51 | gene | gene | 23992 |
| 2001-05-15 10:25:52 | gene | tricia | 998532 |
| 2001-05-12 12:48:13 | tricia | gene | 194925 |
| 2001-05-14 17:03:01 | tricia | phil | 2394482 |
+--------------------------+---------+---------+-----------+

Значение дополнительного столбца сортировки равно 0 для строк, в которых значение srcuser равно phil, и 1 – для остальных строк.


Теперь записи для сообщений, отправленных пользователем phil, «всплывут» на самый верх вывода. (Чтобы вместо этого «утопить» их, то есть спустить в самый низ вывода, задайте обратное направление сортировки при помощи DESC или поменяйте местами второй и третий аргументы функции IF().)

Перемещать можно не только конкретные значения, но и записи, для которых выполнены какие-то условия. Чтобы вывести первыми записи для случаев, когда люди писали письма сами себе, выполним такой запрос:

mysql> SELECT t, srcuser, dstuser, size
-> FROM mail
-> ORDER BY IF(srcuser=dstuser,0,1), srcuser, dstuser;

+--------------------------+---------+----------+----------+
| t | srcuser | dstuser | size |
+--------------------------+---------+----------+----------+
| 2001-05-14 14:42:21 | barb | barb | 98151 |
| 2001-05-15 07:17:48 | gene | gene | 3824 |
| 2001-05-15 17:35:31 | gene | gene | 3856 |
| 2001-05-19 22:21:51 | gene | gene | 23992 |
| 2001-05-12 15:02:49 | phil | phil | 1048 |
| 2001-05-15 08:50:57 | phil | phil | 978 |
| 2001-05-11 10:15:08 | barb | tricia | 58274 |
| 2001-05-13 13:59:18 | barb | tricia | 271 |
| 2001-05-14 09:31:37 | gene | barb | 2291 |
| 2001-05-16 09:00:28 | gene | barb | 613 |
| 2001-05-15 10:25:52 | gene | tricia | 998532 |
| 2001-05-16 23:04:19 | phil | barb | 10294 |
| 2001-05-14 11:52:17 | phil | tricia | 5781 |
| 2001-05-17 12:49:23 | phil | tricia | 873 |
| 2001-05-12 12:48:13 | tricia | gene | 194925 |
| 2001-05-14 17:03:01 | tricia | phil | 2394482 |
+--------------------------+----------+----------+----------+

Если вы хорошо представляете себе содержимое вашей таблицы, то, возможно, сумеете обойтись без дополнительного столбца сортировки.


Например, в таблице mail столбец srcuser никогда не содержит NULL, поэтому предыдущий запрос можно переписать, используя в инструкции ORDER BY на один столбец меньше (считаем, что значения NULL при сортировке располагаются перед всеми значениями не-NULL):

mysql> SELECT t, srcuser, dstuser, size
-> FROM mail
-> ORDER BY IF(srcuser=dstuser,NULL,srcuser), dstuser;

+--------------------------+---------+---------+---------+
| t | srcuser | dstuser | size |
+--------------------------+---------+---------+---------+
| 2001-05-14 14:42:21 | barb | barb | 98151 |
| 2001-05-15 07:17:48 | gene | gene | 3824 |
| 2001-05-15 17:35:31 | gene | gene | 3856 |
| 2001-05-19 22:21:51 | gene | gene | 23992 |
| 2001-05-12 15:02:49 | phil | phil | 1048 |
| 2001-05-15 08:50:57 | phil | phil | 978 |
| 2001-05-11 10:15:08 | barb | tricia | 58274 |
| 2001-05-13 13:59:18 | barb | tricia | 271 |
| 2001-05-14 09:31:37 | gene | barb | 2291 |
| 2001-05-16 09:00:28 | gene | barb | 613 |
| 2001-05-15 10:25:52 | gene | tricia | 998532 |
| 2001-05-16 23:04:19 | phil | barb | 10294 |
| 2001-05-14 11:52:17 | phil | tricia | 5781 |
| 2001-05-17 12:49:23 | phil | tricia | 873 |
| 2001-05-12 12:48:13 | tricia | gene | 194925 |
| 2001-05-14 17:03:01 | tricia | phil | 2394482 |
+--------------------------+----------+---------+-----------+.



Оцените статью: (0 голосов)
0 5 0

Статьи из раздела MySQL на эту тему:
Использование ORDER BY для сортировки результатов запроса
Сортировка IP-адресов в числовом порядке
Сортировка в порядке, определенном пользователем
Сортировка значений ENUM
Сортировка и значения NULL