SQL jak zrobić żeby wartości null były ostatnie przy sortowaniu rosnąco

Mam tabelę SQL z polem datetime. Pole, o którym mowa, może być null. Mam zapytanie i chcę, aby wyniki posortowane ascendingly przez pole datetime, jednak chcę wiersze, w których pole datetime jest null na końcu listy, a nie na początku.

Czy jest na to prosty sposób?

Author: David Božjak, 2009-09-30

13 answers

select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate
 333
Author: RedFilter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-30 14:59:04

("trochę" późno, ale o tym w ogóle nie wspomniano)

Nie podałeś swojego DBMS.

W standardowym SQL (i większości nowoczesnych DBMS, takich jak Oracle, PostgreSQL, DB2, Firebird, Apache Derby, HSQLDB i H2) można określić NULLS LAST lub NULLS FIRST:

Użyj NULLS LAST, aby posortować je do końca:

select *
from some_table
order by some_column DESC NULLS LAST
 132
Author: a_horse_with_no_name,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-23 09:39:22

Ja też się na to natknąłem i wygląda na to, że na MySQL i PostgreSQL działa mi:

ORDER BY date IS NULL, date DESC

Jak znaleziono w https://stackoverflow.com/a/7055259/496209

 29
Author: Luksurious,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:08
order by coalesce(date-time-field,large date in future)
 13
Author: Gratzy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-30 15:03:01

Możesz użyć wbudowanej funkcji, aby sprawdzić, czy nie ma null, jak poniżej. Testuję go i działa dobrze.

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

 12
Author: Majdi M. Aburahelah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-07 09:37:43

Jeśli twój silnik pozwala ORDER BY x IS NULL, x lub ORDER BY x NULLS LAST Użyj tego. Ale jeśli nie to może pomóc:

Jeśli sortujesz według typu numerycznego, możesz to zrobić: (zapożyczenie schematu z inna odpowiedź.)

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

wyniki wyświetlane posortowane według działów z NULL ostatni

Każda liczba inna niż null staje się 0, a null staje się 1, Co sortuje null jako ostatni.

Możesz to również zrobić dla ciągów:

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

wyniki wyświetlane posortowane według LastName z NULL last

Ponieważ 'a' > ''.

To działa nawet z datami, wymuszając do nullable int i używając metody dla ints powyżej:
SELECT *
FROM Employees
ORDER BY ISNULL(CONVERT(INT, HireDate)*0, 1), HireDate

(udawajmy, że schemat został wynajęty.)

Metody te unikają problemu konieczności wymyślania lub zarządzania "maksymalną" wartością każdego typu lub naprawiania zapytań, jeśli typ danych (i maksimum) ulegnie zmianie (oba problemy, z którymi borykają się inne rozwiązania ISNULL). Poza tym są znacznie krótsze niż sprawa.

 9
Author: infogulch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:41
SELECT *          
FROM Employees
ORDER BY ISNULL(DepartmentId, 99999);

Zobacz ten wpis na blogu .

 4
Author: user3923117,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 14:56:13

Gdy twoja kolumna zamówienia jest numeryczna (jak ranga), możesz ją pomnożyć przez -1, a następnie malejąco. Utrzyma kolejność, którą oczekujesz, ale umieść NULL na końcu.

select *
from table
order by -rank desc
 4
Author: Luizgrs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-26 19:12:54

Thanks RedFilter for providing excellent solution to the bugging issue of sorting nullable datetime field.

Używam bazy danych SQL Server do mojego projektu.

Zmiana wartości null datetime na ' 1 ' rozwiązuje problem sortowania dla kolumny DateTime datatype. Jeśli jednak mamy kolumnę z innym typem niż datetime datatype to nie obsługuje.

Aby obsłużyć sortowanie kolumn varchar, próbowałem użyć 'ZZZZZZZ', ponieważ wiedziałem, że kolumna nie ma wartości zaczynających się od "Z". Zadziałało zgodnie z oczekiwaniami.

W tych samych liniach, użyłem wartości max +1 dla int i innych typów danych, aby uzyskać sortowanie zgodnie z oczekiwaniami. To również dało mi wyniki, jakie były wymagane.

Jednak zawsze byłoby idealne, aby uzyskać coś łatwiejszego w samym silniku bazy danych, który mógłby zrobić coś takiego jak:

Order by Col1 Asc Nulls Last, Col2 Asc Nulls First 

Jak wspomniano w odpowiedzi udzielonej przez a_horse_with_no_name.

 3
Author: Kasim Husaini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-26 12:10:30

W Oracle możesz użyć NULLS FIRST lub NULLS LAST: Określa, że wartości NULL powinny być zwracane przed / po wartościach innych niż NULL:

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

Na przykład:

ORDER BY date DESC NULLS LAST

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

 2
Author: Joaquinglezsantos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-30 13:27:10
order by -cast([nativeDateModify] as bigint) desc
 1
Author: paparazzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-08 16:13:52

Rozwiązanie przy użyciu "case" jest uniwersalne, ale wtedy nie używaj indeksów.

order by case when MyDate is null then 1 else 0 end, MyDate
W moim przypadku potrzebowałem wydajności.
 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)  
 1
Author: Adam111p,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-23 12:16:54

Użyj funkcji NVL

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

Oto alternatywa dla NVL w najbardziej znanych DBMS

 0
Author: Charmi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-24 09:58:40