Зачастую необходимо выполнить сортировку по полям, в которых могут присутствовать null-значения, и расположить результирующие строки с такими значениями либо в конце, либо в начале выборки.
Стандартное поведение в MySQL: если мы делаем
order by ASC, то строки с null-значениями сортируемого поля помещаются в начале выборки, если же делаем order by DESC — в конце.Предположим, у нас есть таблица
example со следующей структурой и содержимым:| id | price |
| 1 | 5 |
| 2 | 2 |
| 3 | null |
| 4 | 1 |
1. Попробуем отсортировать данные в порядке возрастания цены, при этом переместить строки с null-значениями в конец.
Обычная сортировка вернет null-значения в начале выборки:
SELECT * FROM example order by price ASC| id | price |
| 3 | null |
| 4 | 1 |
| 2 | 2 |
| 1 | 5 |
Для того чтобы изменить такое поведение сортировки, можно воспользоваться одним из трюков:
SELECT * FROM example order by -price DESCSELECT * FROM example order by ISNULL(price), price ASC| id | price |
| 4 | 1 |
| 2 | 2 |
| 1 | 5 |
| 3 | null |
2. Другая задача: нужно отсортировать выборку в порядке убывания цены, а строки с null-значениями разместить в начале.
По умолчанию после сортировки строки с null-значениями цен будут располагаться в конце выборки:
SELECT * FROM example order by price DESC| id | price |
| 1 | 5 |
| 2 | 2 |
| 4 | 1 |
| 3 | null |
Для того чтобы получить нужный порядок, можно воспользоваться одним из следующих запросов:
SELECT * FROM example order by -price ASCSELECT * FROM example order by ISNULL(price) DESC, price DESC| id | price |
| 3 | null |
| 1 | 5 |
| 2 | 2 |
| 4 | 1 |
Следует заметить, что при сортировке с помощью конструкции
order by -price индекс по полю price (если он есть) не будет задействован, тем самым время выборки может возрасти, а оптимальность плана выполнения запроса — снизиться.