Ich versuche nach Datum zu bestellen. Ich möchte, dass die neuesten Daten zuerst eingehen. Das ist einfach genug, aber es gibt viele Datensätze, die null sind und die vor Datensätzen stehen, die ein Datum haben.
Ich habe ein paar Dinge ohne Erfolg versucht:
ORDER BY ISNULL(Next_Contact_Date, 0)
ORDER BY ISNULL(Next_Contact_Date, 999999999)
ORDER BY coalesce(Next_Contact_Date, 99/99/9999)
Wie kann ich nach Datum bestellen und habe die Nullen zuletzt eingegeben? Der Datentyp ist smalldatetime
.
sql-server
sql-server-2005
tsql
UpHelix
quelle
quelle
Antworten:
smalldatetime
hat Reichweite bis zum 6. Juni 2079, so dass Sie verwenden könnenWenn keine legitimen Aufzeichnungen dieses Datum haben.
Wenn dies keine Annahme ist, bei der Sie sich auf eine robustere Option verlassen möchten, wird nach zwei Spalten sortiert.
ORDER BY CASE WHEN Next_Contact_Date IS NULL THEN 1 ELSE 0 END, Next_Contact_Date
Beide oben genannten Vorschläge können jedoch keinen Index verwenden, um eine Sortierung zu vermeiden und ähnlich aussehende Pläne zu erstellen.
Eine andere Möglichkeit, wenn ein solcher Index existiert, ist
SELECT 1 AS Grp, Next_Contact_Date FROM T WHERE Next_Contact_Date IS NOT NULL UNION ALL SELECT 2 AS Grp, Next_Contact_Date FROM T WHERE Next_Contact_Date IS NULL ORDER BY Grp, Next_Contact_Date
quelle
VARCHAR
Felder angewendet werden (z. B.ORDER BY ISNULL(my_varchar, 'ZZZZZZ')
) und ist äußerst nützlich, insbesondere um Aufträge auf eine bestimmte Weise zu erhalten, wenn sie verwendet werdenGROUP BY . . . GROUPING SETS
. Vielen Dank für die Veröffentlichung.Laut Itzik Ben-Gan, Autor von T-SQL Fundamentals für MS SQL Server 2012 , "sortiert SQL Server standardmäßig NULL- Zeichen vor Nicht- NULL- Werten. Um NULL- Zeichen zum letzten Sortieren zu erhalten, können Sie einen CASE- Ausdruck verwenden, der zurückgibt 1, wenn die Spalte " Next_Contact_Date " NULL ist , und 0, wenn sie nicht NULL ist . Nicht- NULL- Markierungen erhalten 0 vom Ausdruck zurück, daher werden sie vor NULL- Markierungen sortiert (die 1 erhalten). Dieser CASE- Ausdruck wird als erster verwendet Spalte sortieren. " Das Next_Contact_DateSpalte "sollte als zweite Sortierspalte angegeben werden. Auf diese Weise werden Nicht- NULL- Markierungen untereinander korrekt sortiert." Hier ist die Lösungsabfrage für Ihr Beispiel für MS SQL Server 2012 (und SQL Server 2014):
ORDER BY CASE WHEN Next_Contact_Date IS NULL THEN 1 ELSE 0 END, Next_Contact_Date;
Äquivalenter Code mit IIF-Syntax:
quelle
Wenn Ihr SQL nicht unterstützt
NULLS FIRST
oder nichtNULLS LAST
, verwenden Sie am einfachsten den folgendenvalue IS NULL
Ausdruck:die Nullen am Ende setzen (
NULLS LAST
) oderdie Nullen nach vorne setzen. Dies erfordert keine Kenntnis des Spaltentyps und ist leichter zu lesen als der
CASE
Ausdruck.BEARBEITEN: Leider funktioniert dies in anderen SQL-Implementierungen wie PostgreSQL und MySQL, in MS SQL Server jedoch nicht. Ich hatte keinen SQL Server zum Testen und verließ mich auf die Dokumentation von Microsoft und das Testen mit anderen SQL-Implementierungen. Laut Microsoft
value IS NULL
ist dies ein Ausdruck , der wie jeder andere Ausdruck verwendet werden kann. UndORDER BY
soll Ausdrücke nehmen wie jede andere Aussage, die einen Ausdruck nimmt. Aber es funktioniert nicht wirklich.Die beste Lösung für SQL Server scheint daher der
CASE
Ausdruck zu sein.quelle
quelle
Next_Contact_Date
null istExplicit conversion from data type date to bigint is not allowed.
Ein bisschen spät, aber vielleicht findet es jemand nützlich.
Für mich kam ISNULL aufgrund des Tabellenscans nicht in Frage. UNION ALL würde mich brauchen, um eine komplexe Abfrage zu wiederholen, und da ich nur das TOP X ausgewählt hätte, wäre es nicht sehr effizient gewesen.
Wenn Sie das Tischdesign ändern können, können Sie:
Fügen Sie ein weiteres Feld hinzu, nur zum Sortieren, z. B. Next_Contact_Date_Sort.
Erstellen Sie einen Trigger, der dieses Feld mit einem großen (oder kleinen) Wert füllt, je nachdem, was Sie benötigen:
CREATE TRIGGER FILL_SORTABLE_DATE ON YOUR_TABLE AFTER INSERT,UPDATE AS BEGIN SET NOCOUNT ON; IF (update(Next_Contact_Date)) BEGIN UPDATE YOUR_TABLE SET Next_Contact_Date_Sort=IIF(YOUR_TABLE.Next_Contact_Date IS NULL, 99/99/9999, YOUR_TABLE.Next_Contact_Date_Sort) FROM inserted i WHERE YOUR_TABLE.key1=i.key1 AND YOUR_TABLE.key2=i.key2 END END
quelle
Verwenden Sie desc und multiplizieren Sie gegebenenfalls mit -1. Beispiel für aufsteigende int-Reihenfolge mit Nullen zuletzt:
select * from (select null v union all select 1 v union all select 2 v) t order by -t.v desc
quelle
Ich weiß, das ist alt, aber das hat bei mir funktioniert
quelle