Was ist in MS SQL 2000 und 2005 bei einer Datumszeit wie "2008-09-25 12:34:56" der effizienteste Weg, eine Datumszeit zu erhalten, die nur "2008-09-25" enthält?
Duplizierte hier .
Was ist in MS SQL 2000 und 2005 bei einer Datumszeit wie "2008-09-25 12:34:56" der effizienteste Weg, eine Datumszeit zu erhalten, die nur "2008-09-25" enthält?
Duplizierte hier .
Antworten:
Ich muss zugeben, dass ich den von Matt gezeigten Floor-Float-Umbau noch nie gesehen hatte. Ich musste das testen.
Ich habe eine reine Auswahl getestet (die Datum und Uhrzeit zurückgibt und nicht das ist, was wir wollen), die hier herrschende Lösung (Floor-Float), eine hier erwähnte "naive" (Stringconvert) und die hier erwähnte, die ich war mit (wie ich dachte, es war das schnellste).
Ich habe die Abfragen auf einem Testserver MS SQL Server 2005 getestet, der auf einem Win 2003 SP2-Server mit einer Xeon 3-GHz-CPU mit maximalem Speicher (32 Bit, also ca. 3,5 GB) ausgeführt wird. Es ist Nacht, in der ich bin, also läuft die Maschine fast ohne Last im Leerlauf. Ich habe alles für mich.
Hier ist das Protokoll aus meinem Testlauf, das aus einer großen Tabelle mit Zeitstempeln ausgewählt wurde, die bis zur Millisekunden-Ebene variieren. Dieser spezielle Datensatz enthält Daten über 2,5 Jahre. Die Tabelle selbst hat über 130 Millionen Zeilen, deshalb beschränke ich mich auf die oberste Million.
SELECT TOP 1000000 CRETS FROM tblMeasureLogv2
SELECT TOP 1000000 CAST(FLOOR(CAST(CRETS AS FLOAT)) AS DATETIME) FROM tblMeasureLogv2
SELECT TOP 1000000 CONVERT(DATETIME, CONVERT(VARCHAR(10), CRETS, 120) , 120) FROM tblMeasureLogv2
SELECT TOP 1000000 DATEADD(DAY, DATEDIFF(DAY, 0, CRETS), 0) FROM tblMeasureLogv2
SQL Server-Analyse- und Kompilierungszeit: CPU-Zeit = 0 ms, verstrichene Zeit = 1 ms.
(1000000 Zeile (n) betroffen) Tabelle 'tblMeasureLogv2'. Scananzahl 1, logische Lesevorgänge 4752, physische Lesevorgänge 0, Vorlesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Vorlesevorgänge 0.
SQL Server-Ausführungszeiten: CPU-Zeit = 422 ms, verstrichene Zeit = 33803 ms.
(1000000 Zeile (n) betroffen) Tabelle 'tblMeasureLogv2'. Scananzahl 1, logische Lesevorgänge 4752, physische Lesevorgänge 0, Vorlesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Vorlesevorgänge 0.
SQL Server-Ausführungszeiten: CPU-Zeit = 625 ms, verstrichene Zeit = 33545 ms.
(1000000 Zeile (n) betroffen) Tabelle 'tblMeasureLogv2'. Scananzahl 1, logische Lesevorgänge 4752, physische Lesevorgänge 0, Vorlesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Vorlesevorgänge 0.
SQL Server-Ausführungszeiten: CPU-Zeit = 1953 ms, verstrichene Zeit = 33843 ms.
(1000000 Zeile (n) betroffen) Tabelle 'tblMeasureLogv2'. Scananzahl 1, logische Lesevorgänge 4752, physische Lesevorgänge 0, Vorlesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Vorlesevorgänge 0.
SQL Server-Ausführungszeiten: CPU-Zeit = 531 ms, verstrichene Zeit = 33440 ms. SQL Server-Analyse- und Kompilierungszeit: CPU-Zeit = 0 ms, verstrichene Zeit = 1 ms.
SQL Server-Ausführungszeiten: CPU-Zeit = 0 ms, verstrichene Zeit = 1 ms.
Was sehen wir hier?
Konzentrieren wir uns auf die CPU-Zeit (wir betrachten die Konvertierung) und sehen, dass wir die folgenden Zahlen haben:
Pure-Select: 422
Floor-cast: 625
String-conv: 1953
DateAdd: 531
Aus diesem Grund sieht es für mich so aus, als ob die DateAdd (zumindest in diesem speziellen Fall) etwas schneller ist als die Bodengussmethode.
Bevor Sie dorthin gehen, habe ich diesen Test mehrmals ausgeführt, wobei die Reihenfolge der Abfragen geändert wurde und die gleichen Ergebnisse erzielt wurden.
Ist das etwas Seltsames auf meinem Server oder was?
Select DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)
DateDiff (Tag, 0, GetDate ()) ist dasselbe wie DateDiff (Tag, '1900-01-01', GetDate ())
Da DateDiff eine Ganzzahl zurückgibt, erhalten Sie die Anzahl der Tage, die seit dem 1. Januar 1900 vergangen sind. Anschließend fügen Sie diese Ganzzahl die Anzahl der Tage zum 1. Januar 1900 hinzu. Der Nettoeffekt ist das Entfernen der Zeitkomponente.
Ich sollte auch erwähnen, dass diese Methode für jeden Datums- / Zeitabschnitt funktioniert (wie Jahr, Quartal, Monat, Tag, Stunde, Minute und Sekunde).
Select DateAdd(Year, DateDiff(Year, 0, GetDate()), 0)
Select DateAdd(Quarter, DateDiff(Quarter, 0, GetDate()), 0)
Select DateAdd(Month, DateDiff(Month, 0, GetDate()), 0)
Select DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)
Select DateAdd(Hour, DateDiff(Hour, 0, GetDate()), 0)
Select DateAdd(Second, DateDiff(Second, '20000101', GetDate()), '20000101')
Der letzte für Sekunden erfordert eine spezielle Behandlung. Wenn Sie den 1. Januar 1900 verwenden, wird eine Fehlermeldung angezeigt.
Der Unterschied zwischen zwei Datetime-Spalten verursachte zur Laufzeit einen Überlauf.
Sie können diesen Fehler umgehen, indem Sie ein anderes Referenzdatum verwenden (z. B. 1. Januar 2000).
select cast(floor(cast(@datetime as float)) as datetime)
Funktioniert, weil das Umwandeln einer Datumszeit in Float die Anzahl der Tage (einschließlich Bruchteile eines Tages) seit dem 1. Januar 1900 angibt. Durch das Bodenbelag werden die gebrochenen Tage entfernt und die Anzahl der ganzen Tage belassen, die dann auf eine Datumszeit zurückgesetzt werden können.
in SQL Server 2012 verwenden
select cast(getdate() as date)
date
Datentyp fehlt .
select cast(getdate()as varchar(11))as datetime
Verwenden Sie: JJJJ-MM-TT:
select convert(varchar(10), getdate(), 120)
Edit: Ups, er möchte eine DateTime anstelle einer Zeichenfolge. Das Äquivalent von TRUNC () in Oracle. Sie können das, was ich gepostet habe, auf eine DateTime zurückführen:
select convert(datetime, convert(varchar(10), getdate(), 120) , 120)
CONVERT, FLOOR und DATEDIFF funktionieren genauso.
So geben Sie den Datumsteil nur von einem SQL Server-Datetime-Datentyp zurück
Drei Methoden, die im folgenden Link beschrieben werden. Ich habe sie nicht auf Leistung getestet, um festzustellen, welche am schnellsten ist.
CAST(FLOOR(CAST(yourdate AS DECIMAL(12, 5))) AS DATETIME)
leistet bei weitem das Beste. Sie können die Beweise und Tests sehen, wenn Sie das Datum ohne Zeit in SQL Server erhalten
Was ist mit SELECT CAST(CASt(GETDATE() AS int) AS DATETIME)
?
CONVERT(VARCHAR(10), GETDATE(), 120) AS [YYYY-MM-DD]