it-swarm.com.de

Wie kann ich eine Datetime in SQL Server abschneiden?

Was ist der beste Weg, um einen Datetime-Wert in SQL Server 2008 zu kürzen (um Stunden, Minuten und Sekunden zu entfernen)?

Zum Beispiel:

declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)

-----------------------
2009-05-28 00:00:00.000
246
Julio César

Dies sammelt immer wieder zusätzliche Stimmen, auch einige Jahre später, und ich muss sie 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 im unteren Bereich immer noch zutreffen, und Sie müssen oft einen Schritt zurückgehen und einen Weg finden, um den Abguss an erster Stelle zu vermeiden.

Es gibt aber 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 wie den ersten Moment des Monats, die Minute, die Stunde oder das Jahr anpassen kann.

Dieser korrekte Weg verwendet dokumentierte Funktionen, die zum ANSI-Standard gehören und garantiert funktionieren, aber es kann etwas langsamer sein. Sie finden heraus, wie viele Tage vom Tag 0 bis zum aktuellen Tag vorhanden sind, und fügen diese Tage bis zum Tag 0 hinzu. Es funktioniert unabhängig davon, wie Ihre Datumszeit gespeichert ist und wie Ihr Gebietsschema ist.

Der schnelle Weg:

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

Dies funktioniert, weil datetime-Spalten als binäre 8-Byte-Werte gespeichert werden. Werfen Sie sie zum Floaten, setzen Sie sie ab, um den Bruch zu entfernen, und der Zeitanteil der Werte ist weg, wenn Sie sie auf datetime zurückwerfen. Es ist alles nur ein bisschen verschoben ohne komplizierte Logik und es ist sehr schnell. 

Beachten Sie, dass dies auf einem Implementierungsdetail beruht, das Microsoft jederzeit ändern kann, selbst bei einem automatischen Service-Update. Es ist auch nicht sehr tragbar. In der Praxis ist es sehr unwahrscheinlich, dass sich diese Implementierung bald ändern wird. Es ist jedoch immer noch wichtig, sich der Gefahr bewusst zu sein, wenn Sie sie verwenden. Und jetzt, da wir die Option haben, ein Datum festzulegen, ist dies selten notwendig.

Der falsche Weg:

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

Der falsche Weg funktioniert, indem Sie in einen String konvertieren, den String abschneiden und wieder in eine Datumszeit konvertieren. Es ist falsch aus zwei Gründen: 1) es funktioniert möglicherweise nicht in allen Gebietsschemas und 2) es geht um die langsamste Möglichkeit, dies zu tun ... und nicht nur ein bisschen; es ist wie eine Größenordnung oder zwei langsamer als die anderen Optionen. 


Update Dies hat in letzter Zeit einige Stimmen erhalten, und ich möchte hinzufügen, dass seit ich dies gepostet habe, ich ziemlich überzeugende Beweise gesehen habe, dass SQL Server den Leistungsunterschied zwischen "richtiger" Art und Weise optimieren wird "schneller" Weg, was bedeutet, dass Sie den ehemaligen bevorzugen sollten.

In beiden Fällen möchten Sie Ihre Abfragen schreiben, um zu vermeiden, dass Sie dies an erster Stelle tun müssen . Es ist sehr selten, dass Sie diese Arbeit an der Datenbank ausführen sollten. 

In den meisten Fällen ist die Datenbank bereits Ihr Engpass. Es ist in der Regel der Server, der am teuersten für das Hinzufügen von Hardware für Leistungsverbesserungen ist und der schwierigste, um diese Ergänzungen richtig zu machen (beispielsweise müssen Festplatten mit Speicher abgeglichen werden). Es ist auch am schwierigsten, sowohl technisch als auch geschäftlich nach außen zu skalieren. Es ist technisch wesentlich einfacher, einen Web- oder Anwendungsserver als einen Datenbankserver hinzuzufügen, und selbst wenn das falsch ist, zahlen Sie nicht mindestens 20.000 US-Dollar pro Serverlizenz für IIS oder Apache. 

Ich möchte hier darauf hinweisen, dass Sie diese Arbeit nach Möglichkeit auf der Anwendungsebene ausführen sollten. Der nur -Zeitpunkt, zu dem Sie jemals eine Datetime auf dem Sql-Server abschneiden sollten, ist der Zeitpunkt, zu dem Sie sich gruppieren müssen, und selbst dann sollten Sie wahrscheinlich eine zusätzliche Spalte als berechnete Spalte einrichten, die beim Einfügen verwaltet wird/Aktualisierungszeit oder in Anwendungslogik gepflegt. Holen Sie sich diese indexbrechende, CPU-lastige Arbeit aus Ihrer Datenbank.

443
Joel Coehoorn

Nur für SQL Server 2008

CAST(@SomeDateTime AS Date) 

Dann werfen Sie es zurück auf datetime, wenn Sie möchten

CAST(CAST(@SomeDateTime AS Date) As datetime)
44
DJ.

Nur für eine vollständigere Antwort, hier ist ein Weg, um auf alle Datumsteile herunterzufahren, einschließlich Minuten (Ersetzen Sie GETDATE() durch das Datum, das gekürzt werden soll).

Dies unterscheidet sich von der akzeptierten Antwort dahingehend, dass Sie nicht nur dd (Tage), sondern einen beliebigen Datumsteil (siehe hier ) verwenden können:

dateadd(minute, datediff(minute, 0, GETDATE()), 0)

Beachten Sie, dass der 0 im obigen Ausdruck ein konstantes Datum am Anfang eines Jahres ist (1900-01-01). Wenn Sie auf kleinere Teile wie Sekunden oder Millisekunden verkürzen müssen, müssen Sie ein konstantes Datum annehmen, das näher an dem zu schneidenden Datum liegt, um einen Überlauf zu vermeiden.

20
Lucero

Der Ausschnitt, den ich im Web gefunden habe, als ich dies tun musste, war

 dateadd(dd,0, datediff(dd,0, YOURDATE))
 e.g.
 dateadd(dd,0, datediff(dd,0, getDate()))
7
Tom Ritter
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)
1
Dean

In SQl 2005 könnte Ihre Funktion trunc_date so geschrieben werden.

(1)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
    CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END

Die erste Methode ist viel sauberer. Es verwendet nur 3 Methodenaufrufe einschließlich des finalen CAST () und führt keine Verkettung von Zeichenfolgen durch, was ein automatisches Plus darstellt. Außerdem gibt es hier keine großen Typen. Wenn Sie sich vorstellen können, dass Datums-/Zeitstempel dargestellt werden können, ist das Konvertieren von Datumsangaben in Zahlen und zurück in Datumsangaben ein relativ einfacher Vorgang.

(2)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
      SELECT CONVERT(varchar, @date,112)
END

Wenn Sie Bedenken hinsichtlich der Implementierung von Datumsangaben (2) oder (3) von Microsoft haben, kann dies in Ordnung sein.

(3)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CAST((STR( YEAR( @date ) ) + '/' +STR( MONTH( @date ) ) + '/' +STR( DAY(@date ) )
) AS DATETIME
END

Drittens die ausführlichere Methode. Dies erfordert das Aufteilen des Datums in die Teile Jahr, Monat und Tag, das Zusammenstellen im Format "JJJJ/MM/TT" und das anschließende Zurücksetzen auf ein Datum. Diese Methode umfasst 7 Methodenaufrufe, einschließlich der finalen CAST () - und der String-Verkettung.

1
AlejandroR

sie könnten dies einfach tun (SQL 2008):

declare @SomeDate date = getdate ()

select @SomeDate

2009-05-28

wählen Sie cast (floor (cast (getdate () as float)) als datetime) .__ aus. Referenzieren Sie diese: http://microsoftmiles.blogspot.com/2006/11/remove-time-fromdatetime-in-ssll -server.html

0

Orakel: 

TRUNC(SYSDATE, 'MONTH')

SQL Server: 

DATEADD(DAY, - DATEPART(DAY, DateField) + 1, DateField)

Könnte auf ähnliche Weise zum Abschneiden von Minuten oder Stunden von einem Datum verwendet werden.

0
Markus

Für diejenigen, die hierher gekommen sind, um nach einem Weg zu suchen, um ein DATETIME-Feld auf etwas weniger als einen ganzen Tag zu verkürzen, beispielsweise jede Minute, können Sie Folgendes verwenden:

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) + (FLOOR((CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))) * 1440.0) + (3.0/86400000.0)) / 1440.0 AS DATETIME)

wenn heute also 2010-11-26 14:54:43.123 wäre, würde dies 2010-11-26 14:54:00.000 zurückgegeben werden.

Ersetzen Sie 1440.0 durch die Anzahl der Intervalle an einem Tag, um das Intervall zu ändern, auf das es sich verkürzt:

24hrs          =   24.0  (for every hour)
24hrs / 0.5hrs =   48.0  (for every half hour)
24hrs / (1/60) = 1440.0  (for every minute)

(Setzen Sie am Ende immer einen .0, um implizit in einen Float umgewandelt zu werden.)


Diejenigen, die sich fragen, wozu der (3.0/86400000) in meiner Berechnung dient, scheinen SQL Server 2005 nicht FLOAT in DATETIME genau umzuwandeln, so dass dies 3 Millisekunden vor dem Platzieren fügt.

0
BG100

Diese Abfrage sollte ein Ergebnis ergeben, das trunc(sysdate) in Oracle entspricht.

SELECT  * 
FROM    your_table
WHERE   CONVERT(varchar(12), your_column_name, 101)
      = CONVERT(varchar(12), GETDATE(), 101)

Hoffe das hilft!

0
Sandeep Gaadhe

Sie können auch das Datum using Substring aus der datetime-Variablen extrahieren. Bei der Zurücksetzung auf datetime wird der Zeitteil ignoriert.

declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime) 

Sie können auch auf Teile der datetime-Variablen zugreifen und sie mit einem verkürzten Konstrukt zusammenführen, etwa wie folgt:

SELECT cast(DATENAME(year, @Somedate) + '-' + 
       Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
       DATENAME(day, @Somedate) 
       as datetime)
0
NeverHopeless