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



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



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

685   13  

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'>''.

это даже работает с датами, принуждая к нулю 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, а затем упорядочить по убыванию. Он сохранит порядок, который вы ожидаете, но поставит NULL последним.

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: указывает, что нулевые значения должны быть возвращены до / после ненулевых значений:

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 в самых известных СУБД

Comments

    Ничего не найдено.