Rundung von SQL DateTime auf Mitternacht


79

Ich habe ein kleines Problem mit meiner SQL-Abfrage. Ich verwende die GETDATE-Funktion. Nehmen wir jedoch an, ich führe das Skript um 17:00 Uhr aus. Es werden Datensätze zwischen dem 12.12.2011, 17:00 Uhr und dem 18.12.2011, 17:00 Uhr abgerufen. Wie kann ich dafür sorgen, dass Rekorde für den gesamten 12.12.2011 - 18.12.2011 abgerufen werden?

Mein Skript:

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate > (GETDATE()-6)  

Antworten:


114

In SQL Server 2008 und höher können Sie das DateTimein a Dateumwandeln, wodurch das Zeitelement entfernt wird.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= (cast(GETDATE()-6 as date))  

In SQL Server 2005 und darunter können Sie Folgendes verwenden:

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= DateAdd(Day, Datediff(Day,0, GetDate() -6), 0)

1
Ich habe dieses Typdatum ist kein definierter Systemtyp.
Henryaaron

2
Ich denke, Sie verwenden SQL 2008 dann nicht :)
DaveShaw

@ user1090389 Deshalb habe ich die String-Konvertierungsoption gesetzt; D
Bassam Mehanni

@ DaveShaw - Fehlen eines DATEADD dort
MatBailie

Sorry @Dems Dave sieht weniger kompliziert aus
Henryaaron

54

Hier ist das Einfachste, was ich gefunden habe

-- Midnight floor of current date

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()))

Der DATEDIFF gibt die ganzzahlige Anzahl von Tagen vor oder seit 1900-1-1 zurück, und die Convert Datetime bringt sie verbindlich auf dieses Datum um Mitternacht zurück.

Da DateDiff eine Ganzzahl zurückgibt, können Sie Tage addieren oder subtrahieren, um den richtigen Offset zu erhalten.

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()) + @dayOffset)

Das rundet nicht ab, das schneidet ab ... Aber ich denke, das wird gefragt. (Um eine zu runden, fügen Sie eine hinzu und schneiden Sie sie ab ... und das rundet auch nicht die Decke ab, sondern höchstwahrscheinlich das, was Sie wollen. Um wirklich zu runden, fügen Sie 0,5 hinzu (funktioniert das?) Und schneiden Sie ab.

Es stellt sich heraus, dass Sie GetDate () .5 hinzufügen können, und es funktioniert wie erwartet.

-- Round Current time to midnight today or midnight tomorrow

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE() + .5))

Ich habe alle meine Versuche mit SQL Server 2008 durchgeführt, aber ich denke, diese Funktionen gelten auch für 2005.


Dies funktioniert in 2k5 gerade getestet. where [ScanDate] >= convert(datetime, datediff(day, 0, getdate())) and [ScanDate] < convert(datetime, datediff(day, -1, getdate()))
Nulltron

9
--
-- SQL DATEDIFF getting midnight time parts 
--
SELECT GETDATE() AS Now, 
   Convert(DateTime, DATEDIFF(DAY, 0, GETDATE())) AS MidnightToday,
   Convert(DateTime, DATEDIFF(DAY, -1, GETDATE())) AS MidnightNextDay,
   Convert(DateTime, DATEDIFF(DAY, 1, GETDATE())) AS MidnightYesterDay
go
Now                   MidnightToday          MidnightNextDay        MidnightYesterDay     
 --------------------  ---------------------  ---------------------  --------------------- 
 8/27/2014 4:30:22 PM  8/27/2014 12:00:00 AM  8/28/2014 12:00:00 AM  8/26/2014 12:00:00 AM 

5
SELECT getdate()

Ergebnis: 2012-12-14 16: 03: 33.360

SELECT convert(datetime,convert(bigint, getdate()))

Ergebnis 15.12.2012 00: 00: 00.000


1
Danke für die Rückmeldung. Was ich hervorheben wollte, ist, dass der Konverter zu Bigint und zurück die Rundung für Sie übernimmt.
Jeremy Atkinson

1
Dieser Code rundet es bis Mitternacht am Ende des Tages auf, wenn die Zeit nach Mittag liegt, was dazu führt, dass dies für den halben Tag falsch ist.
ChrisM

Die Verwendung dieser Methode kann später bei größeren Datenmengen zu Leistungseinbußen führen.
Taco

3

Wie bereits in @BassamMehanni erwähnt, können Sie ab SQL Server 2008 als DATE umwandeln ...

SELECT
  *
FROM
  yourTable
WHERE
      dateField >= CAST(GetDate() - 6 AS DATE)
  AND dateField <  CAST(GetDate() + 1 AS DATE)

Die zweite Bedingung kann tatsächlich gerecht sein GetDate(), aber ich zeige dieses Format als Beispiel Less Than DateXdafür, dass das dateField nicht auch in ein DATE umgewandelt werden muss, wodurch die Leistung massiv verbessert wird.


Wenn Sie 2005 oder jünger sind, können Sie dies verwenden ...

SELECT
  *
FROM
  yourTable
WHERE
      dateField >= DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) - 6, 0)
  AND dateField <  DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) + 1, 0)

3

Versuchen Sie es damit.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= CONVERT(DATE, GETDATE())

1

Das mag billig aussehen, aber es funktioniert bei mir

SELECT CONVERT (DATETIME, LEFT (CONVERT (VARCHAR, @ dateFieldOrVariable, 101), 10) + '00: 00: 00.000')


1

Sie können die Uhrzeit in ein Datum und dann wieder in eine Uhrzeit konvertieren. Dadurch wird der Zeitstempel zurückgesetzt.

Wählen Sie getdate () --2020-05-05 13: 53: 35.863

Wählen Sie Besetzung (Besetzung (GETDATE () als Datum) als Datum / Uhrzeit) --2020-05-05 00: 00: 00.000

0

Normalerweise mache ich

SELECT *
FROM MyTable
WHERE CONVERT(VARCHAR, MyTable.dateField, 101) = CONVERT(VARCHAR, GETDATE(), 101)

Wenn Sie SQL SERVER 2008 verwenden, können Sie dies tun

SELECT *
FROM MyTable
WHERE CAST(MyTable.dateField AS DATE) = CAST(GETDATE() AS DATE)

Hoffe das hilft


3
Wenn Sie das erste Beispiel verwenden, zerstören Sie die Fähigkeit des Optimierers, Indizes usw. zu verwenden. Die Verwendung von String-Funktionen für Datumsarithmetik und Vergleiche ist eine sehr schlechte Idee. Es sollte nie (imo) erwähnt werden, es ist eine so schlechte Option.
MatBailie

Sie müssen nicht, wenn Sie SQL Server 2008 verwenden, andernfalls bin ich mir nicht sicher, wie Sie es sonst in SQL Server 2000/2005 tun könnten. Ein Beispiel wäre dankbar, danke.
Bassam Mehanni

Um fair zu sein. Beide Optionen zerstören die Fähigkeit des Optmizers, Indizes zu verwenden. Sie sollten die Filterprädikatspalte ausführen und funktionsfähig machen. Dies schließt Abgüsse ein.
Pimbrouwers

0

Sie könnten die Zeit abrunden.

Wenn Sie ROUNDunten verwenden, wird es auf Mitternacht abgerundet.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >  CONVERT(datetime, (ROUND(convert(float, getdate()-6.5),0)))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.