Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie kann ich eine Datumszeit in SQL Server abschneiden?

Dies sammelt weiterhin häufig zusätzliche Stimmen, auch mehrere Jahre später, und daher muss ich es für moderne Versionen von Sql Server aktualisieren. Für SQL Server 2008 und höher ist es einfach:

cast(getDate() As Date)

Beachten Sie, dass die letzten drei Absätze ganz unten immer noch gelten und Sie oft einen Schritt zurücktreten und einen Weg finden müssen, den Cast von vornherein zu vermeiden.

Aber es gibt auch andere Möglichkeiten, dies zu erreichen. Hier sind die häufigsten.

Der richtige Weg (neu seit Sql Server 2008):

cast(getdate() As Date)

Der richtige Weg (alt):

dateadd(dd, datediff(dd,0, getDate()), 0)

Dies ist jetzt älter, aber es ist immer noch wissenswert, da es sich auch leicht für andere Zeitpunkte anpassen lässt, wie z. B. den ersten Moment des Monats, Minute, Stunde oder Jahr.

Dieser korrekte Weg verwendet dokumentierte Funktionen, die Teil des ANSI-Standards sind und garantiert funktionieren, aber er kann etwas langsamer sein. Es funktioniert, indem ermittelt wird, wie viele Tage vom Tag 0 bis zum aktuellen Tag vergangen sind, und diese Anzahl Tage zum Tag 0 zurückgezählt werden. Es funktioniert unabhängig davon, wie Ihre Datumszeit gespeichert ist und unabhängig von Ihrem Gebietsschema.

Der schnelle Weg:

cast(floor(cast(getdate() as float)) as datetime)

Dies funktioniert, weil datetime-Spalten als 8-Byte-Binärwerte gespeichert werden. Gießen Sie sie, um zu schweben, füllen Sie sie, um den Bruch zu entfernen, und der Zeitteil der Werte ist weg, wenn Sie sie auf datetime zurückwerfen. Es ist alles nur eine kleine Verschiebung ohne komplizierte Logik und es ist sehr schnell.

Beachten Sie, dass dies von einem Implementierungsdetail abhängt, das Microsoft jederzeit ändern kann, auch bei einem automatischen Dienstupdate. Es ist auch nicht sehr portabel. In der Praxis ist es sehr unwahrscheinlich, dass sich diese Implementierung in absehbarer Zeit ändern wird, aber es ist dennoch wichtig, sich der Gefahr bewusst zu sein, wenn Sie sich dafür entscheiden, sie zu verwenden. Und jetzt, da wir die Möglichkeit haben, als Datum zu übertragen, ist dies selten erforderlich.

Der falsche Weg:

cast(convert(char(11), getdate(), 113) as datetime)

Der falsche Weg funktioniert durch Konvertieren in eine Zeichenfolge, Abschneiden der Zeichenfolge und Zurückkonvertieren in eine Datumszeit. Es ist falsch , aus zwei Gründen:1) es funktioniert möglicherweise nicht in allen Gebietsschemas und 2) es ist der langsamstmögliche Weg, dies zu tun ... und nicht nur ein bisschen; es ist wie eine oder zwei Größenordnungen langsamer als die anderen Optionen.

Aktualisieren Dies hat in letzter Zeit einige Stimmen erhalten, und deshalb möchte ich hinzufügen, dass ich, seit ich dies gepostet habe, einige ziemlich solide Beweise dafür gesehen habe, dass Sql Server den Leistungsunterschied zwischen dem "richtigen" Weg und dem "schnellen" Weg optimieren wird. was bedeutet, dass Sie jetzt Ersteres bevorzugen sollten.

In jedem Fall möchten Sie Ihre Abfragen so schreiben, dass Sie dies gar nicht erst tun müssen . Es ist sehr selten, dass Sie diese Arbeit an der Datenbank durchführen sollten.

An den meisten Stellen ist die Datenbank bereits Ihr Flaschenhals. Es ist im Allgemeinen der Server, bei dem es am teuersten ist, Hardware für Leistungsverbesserungen hinzuzufügen, und bei dem es am schwierigsten ist, diese Ergänzungen richtig hinzubekommen (Sie müssen beispielsweise Festplatten mit Speicher ausgleichen). Es ist auch am schwierigsten nach außen zu skalieren, sowohl technisch als auch aus geschäftlicher Sicht; Es ist technisch viel einfacher, einen Web- oder Anwendungsserver hinzuzufügen als einen Datenbankserver, und selbst wenn das falsch wäre, zahlen Sie nicht mehr als 20.000 US-Dollar pro Serverlizenz für IIS oder Apache.

Der Punkt, den ich zu machen versuche, ist, dass Sie diese Arbeit wann immer möglich auf Anwendungsebene erledigen sollten. Die nur Zeit, in der Sie jemals eine Datumszeit auf SQL Server kürzen sollten, ist, wenn Sie nach Tag gruppieren müssen, und selbst dann sollten Sie wahrscheinlich eine zusätzliche Spalte als berechnete Spalte einrichten, zum Zeitpunkt des Einfügens/Aktualisierens oder in der Anwendung beibehalten Logik. Holen Sie sich diese indexbrechende, CPU-lastige Arbeit aus Ihrer Datenbank.