MySQL Orderby по числу, нуля последний

239

В моем заявлении я делаю очень простой OrderBy.

SELECT * FROM tablename WHERE visible=1 ORDER BY position ASC, id DESC

Проблема заключается в том, что записи NULL для "позиции" обрабатываются как 0. Поэтому все записи с позицией NULL отображаются перед теми, у кого 1,2,3,4. например:

NULL, NULL, NULL, 1, 2, 3, 4

Есть ли способ добиться следующего порядка:

1, 2, 3, 4, NULL, NULL, NULL.
  • 8
    Вам следует пересмотреть ответ пользователя 1052545. Это проще, не требует знания максимальных значений и может быть быстрее (при условии, что вычисление выражения может быть быстрее, чем вызов функции).
Теги:
order
sql-order-by

10 ответов

491
Лучший ответ

MySQL имеет недокументированный синтаксис для сортировки нулей в последний раз. Поместите знак минус (-) перед именем столбца и переключите ASC в DESC:

SELECT * FROM tablename WHERE visible=1 ORDER BY -position DESC, id DESC

Это, по сути, обратное значение position DESC, поместив значения NULL последним, но в остальном же как position ASC.

Хорошая ссылка здесь http://troels.arvin.dk/db/rdbms#select-order_by

  • 72
    Это не документировано, - col_name является выражением ( 0 - col_name ), которое принимает предложение ORDER BY. Конечно, это работает только для числовых столбцов.
  • 7
    Хороший. Работает и для столбцов date и time ! (MySQL 5.5). Я думаю (мне лень проверять) это работает для всех числовых столбцов (timestamp, float ...).
Показать ещё 11 комментариев
284

Я нашел это хорошим решением по большей части:

SELECT * FROM table ORDER BY ISNULL(field), field ASC;
  • 5
    Без переопределения порядка по произведениям: SELECT * FROM table ORDER BY ISNULL(field) ASC; (MySQL 5.5)
  • 1
    Ницца! Я использую этот вариант для пустых полей: SELECT *, position = '' as has_position FROM table ORDER BY has_position, position
Показать ещё 16 комментариев
24

Что-то вроде

SELECT * FROM tablename where visible=1 ORDER BY COALESCE(position, 999999999) ASC, id DESC

Замените 999999999 тем, что максимальное значение для поля

  • 1
    Это решение хрупкое и может привести к периодическим ошибкам
5

NULL LAST

SELECT * FROM table_name ORDER BY id IS NULL, id ASC
  • 4
    Почему проголосовали? Этот ответ полностью действителен: sqlfiddle.com/#!9/e14492/11
4

Попробуйте использовать этот запрос:

SELECT * FROM tablename
WHERE visible=1 
ORDER BY 
CASE WHEN position IS NULL THEN 1 ELSE 0 END ASC,id DESC
  • 0
    Нет необходимости в случае. IS NULL возвращает 1, когда выражение NULL. Смотрите ответ ревербации.
3
SELECT * FROM tablename WHERE visible=1 ORDER BY CASE WHEN `position` = 0 THEN 'a' END , position ASC
  • 5
    Почему ОП должен попробовать это ? Хорошие ответы всегда будут содержать объяснение того, что было сделано и почему это было сделано не только для ОП, но и для будущих посетителей SO, которые могут найти этот вопрос и прочитать ваш ответ.
3

Вы можете coalesce ваши NULL в инструкции ORDER BY:

select * from tablename
where <conditions>
order by
    coalesce(position, 0) ASC, 
    id DESC

Если вы хотите, чтобы NULL сортировались в нижней части, попробуйте coalesce(position, 100000). (Сделайте второе число больше, чем все остальные position в db.)

3

Вы можете поменять местами NULL с другим значением для их сортировки сначала (например, 0 или -1) или последним (большое число или буква)...

SELECT field1, IF(field2 IS NULL, 9999, field2) as ordered_field2
  FROM tablename
 WHERE visible = 1
 ORDER BY ordered_field2 ASC, id DESC
  • 0
    Это не решит проблему, поскольку индекс, на который ссылается ORDER BY, не будет затронут заменой значений в инструкции SELECT и, следовательно, не исправит порядок. Также ознакомьтесь с функцией COALESCE, которая функционально эквивалентна использованию вами функции IF.
  • 0
    Если вы правильно используете псевдоним оператора IF, строки упорядочиваются так, как вы ожидаете. Я исправил мой пример.
2

Для столбца DATE вы можете использовать:


NULLS last:

ORDER BY IFNULL(`myDate`, '9999-12-31') ASC

Бланки последние:

ORDER BY IF(`myDate` = '', '9999-12-31', `myDate`) ASC
-8

Почему вы не заказываете NULLS LAST?

SELECT * 
FROM tablename
WHERE visible = 1 
ORDER BY position ASC NULLS LAST, id DESC 
  • 0
    NULLS LAST - какая версия MySQL была представлена?
  • 1
    Loos, как это не работает с MySQL, только SQL
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню