SQL как сделать значения null последними при сортировке по возрастанию

У меня есть таблица SQL с полем datetime. Поле может быть null. У меня есть запрос, и я хочу, чтобы результаты были отсортированы по полю datetime, однако мне нужны строки, где поле datetime равно null в конце списка, а не в начале.

есть ли простой способ сделать это?

13 ответов


select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate

("немного" поздно, но об этом вообще не упоминалось)

вы не указали свою СУБД.

в стандартном SQL (и большинстве современных СУБД, таких как Oracle, PostgreSQL, DB2, Firebird, Apache Derby, HSQLDB и H2) вы можете указать NULLS LAST или NULLS FIRST:

использовать NULLS LAST чтобы отсортировать их до конца:

select *
from some_table
order by some_column DESC NULLS LAST

Я также просто наткнулся на это, и следующее, кажется, делает трюк для меня, на MySQL и PostgreSQL:

ORDER BY date IS NULL, date DESC

на https://stackoverflow.com/a/7055259/496209


order by coalesce(date-time-field,large date in future)

вы можете использовать встроенную функцию для проверки null или not null, как показано ниже. Я тестирую его, и он работает нормально.

select MyDate from MyTable order by ISNULL(MyDate,1) DESC, MyDate ASC;


если ваш двигатель позволяет ORDER BY x IS NULL, x или ORDER BY x NULLS LAST использовать. Но если это не так, это может помочь:

если вы сортируете по числовому типу, вы можете сделать следующее: (заимствование схемы из еще один ответ.)

SELECT *          
FROM Employees
ORDER BY ISNULL(DepartmentId*0,1), DepartmentId;

result showing sorted by DepartmentId with nulls last

любое ненулевое число становится 0, а нули становятся 1, что сортирует нули последними.

вы также можете сделать это для строки:

SELECT *
FROM Employees
ORDER BY ISNULL(LEFT(LastName,0),'a'), LastName

result showing sorted by LastName with nulls last

, потому что 'a'>''.

это даже работает с датами, принуждая к nullable int и используя метод для ints выше:

SELECT *
FROM Employees
ORDER BY ISNULL(CONVERT(INT, HireDate)*0, 1), HireDate

(давайте сделаем вид, что схема HireDate.)

эти методы избегают проблемы необходимости придумывать или управлять "максимальным" значением каждого типа или исправлять запросы, если тип данных (и максимум) изменяется (обе проблемы, которые другие ISNULL решения страдают). К тому же они намного короче дела.


SELECT *          
FROM Employees
ORDER BY ISNULL(DepartmentId, 99999);

посмотреть этот блог.


когда ваш столбец заказа числовой (например, ранг), вы можете умножить его на -1, а затем заказать по убыванию. Он будет держать заказ вы expecing но поставить нуль в прошлом.

select *
from table
order by -rank desc

спасибо RedFilter за предоставление отличного решения проблемы подслушивания сортировки поля nullable datetime.

Я использую базу данных SQL Server для своего проекта.

изменение значения datetime null на " 1 " решает проблему сортировки столбца типа данных datetime. Однако если у нас есть столбец с типом данных датавремя, то он не сумеет справиться.

для обработки сортировки столбцов varchar я попытался использовать "ZZZZZZZ" , поскольку знал, что столбец не имеет значения, начинающиеся с 'Z'. Все получилось, как и ожидалось.

в тех же строках я использовал max values +1 для int и других типов данных, чтобы получить сортировку, как ожидалось. Это также дало мне необходимые результаты.

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

Order by Col1 Asc Nulls Last, Col2 Asc Nulls First 

как указано в ответе, предоставленном a_horse_with_no_name.


в Oracle, вы можете использовать NULLS FIRST или NULLS LAST: указывает, что значения NULL должны быть возвращены до / после ненулевых значений:

ORDER BY { column-Name | [ ASC | DESC ] | [ NULLS FIRST | NULLS LAST ] }

например:

ORDER BY date DESC NULLS LAST

Ref:http://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj13658.html


order by -cast([nativeDateModify] as bigint) desc

решение с использованием "case" является универсальным, но тогда не используйте индексы.

order by case when MyDate is null then 1 else 0 end, MyDate

в моем случае, мне нужна производительность.

 SELECT smoneCol1,someCol2  
 FROM someSch.someTab
 WHERE someCol2 = 2101 and ( someCol1 IS NULL ) 
  UNION   
 SELECT smoneCol1,someCol2
 FROM someSch.someTab
 WHERE someCol2 = 2101 and (  someCol1 IS NOT NULL)  

использовать функцию NVL

  select * from MyTable order by NVL(MyDate, to_date('1-1-1','DD-MM-YYYY'))

здесь альтернатива NVL в самых известных СУБД