Vergleichen Sie DATETIME und DATE, wobei Sie den Zeitanteil ignorieren

151

Ich habe zwei Tabellen, in denen Spalte [date]Typ ist DATETIME2(0).

Ich muss zwei Datensätze nur anhand ihrer Datumsteile (Tag + Monat + Jahr) vergleichen und Zeitteile (Stunden + Minuten + Sekunden) verwerfen.

Wie kann ich das machen?

abatishchev
quelle

Antworten:

252

Verwenden Sie den CASTneuen DATEDatentyp in SQL Server 2008, um nur den Datumsteil zu vergleichen:

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)
marc_s
quelle
61

Ein kleiner Nachteil in Marc's Antwort ist, dass beide Datumsfelder typisiert wurden, was bedeutet, dass Sie keine Indizes nutzen können.

Wenn also eine Abfrage geschrieben werden muss, die von einem Index für ein Datumsfeld profitieren kann, ist der folgende (ziemlich komplizierte) Ansatz erforderlich.

  • Das indizierte Datumsfeld (nennen wir es DF1) muss von keiner Funktion unberührt bleiben.
  • Sie müssen also DF1 mit dem gesamten Bereich der Datums- / Uhrzeitwerte für den Tag von DF2 vergleichen.
  • Das ist vom Datumsteil von DF2 bis zum Datumsteil des Tages nach DF2.
  • Dh (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
  • HINWEIS : Es ist sehr wichtig, dass der Vergleich > = (Gleichheit zulässig) zum Datum von DF2 und (streng) < am Tag nach DF2 ist. Auch der BETWEEN-Operator funktioniert nicht, weil er auf beiden Seiten Gleichheit zulässt.

PS: Eine andere Möglichkeit, nur das Datum zu extrahieren (in älteren Versionen von SQL Server), besteht darin, einen Trick zu verwenden, wie das Datum intern dargestellt wird.

  • Wirf das Datum als Float.
  • Schneiden Sie den Bruchteil ab
  • Setzen Sie den Wert auf ein Datum / eine Uhrzeit zurück
  • Dh CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)
Desillusioniert
quelle
5

Obwohl ich die als richtig markierte Antwort positiv bewertet habe. Ich wollte ein paar Dinge für jeden ansprechen, der darüber stolpert.

Im Allgemeinen, wenn Sie Filtern speziell auf Datum Werte allein. Microsoft empfiehlt die Verwendung des sprachneutralen Formats von ymdoder y-m-d.

Beachten Sie, dass das Formular '2007-02-12' nur für die Datentypen DATE, DATETIME2 und DATETIMEOFFSET als sprachneutral betrachtet wird.

Ein Datumsvergleich mit dem oben genannten Ansatz ist einfach. Betrachten Sie das folgende, erfundene Beispiel.

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    CONVERT(char(8), OrderDate, 112) = @filterDate

In einer perfekten Welt sollten Manipulationen an der gefilterten Spalte vermieden werden, da dies verhindern kann, dass SQL Server Indizes effizient verwendet. Wenn sich die von Ihnen gespeicherten Daten jedoch immer nur auf das Datum und nicht auf die Uhrzeit beziehen, sollten Sie die Speicherung DATETIMEmit Mitternacht als Uhrzeit in Betracht ziehen . Weil:

Wenn SQL Server das Literal in den Typ der gefilterten Spalte konvertiert, wird Mitternacht angenommen, wenn kein Zeitabschnitt angegeben ist. Wenn ein solcher Filter alle Zeilen ab dem angegebenen Datum zurückgeben soll, müssen Sie sicherstellen, dass Sie alle Werte mit Mitternacht als Uhrzeit speichern.

Angenommen, Sie befassen sich nur mit dem Datum und speichern Ihre Daten als solche. Die obige Abfrage kann vereinfacht werden zu:

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    OrderDate = @filterDate
Zuhälter
quelle
3

Sie können diesen versuchen

CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')

Ich teste das für MS SQL 2014 anhand des folgenden Codes

select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
            else '' end
reza.cse08
quelle
-3

Zum Vergleichen Sie zwei Daten wie MM / TT / JJJJ mit MM / TT / JJJJ . Denken Sie daran, dass der Spaltentyp des Felds als erstes dateTime sein muss. Beispiel: Spaltenname: Zahlungsdatum Datentyp : DateTime .

danach können Sie es leicht vergleichen. Abfrage ist:

select  *  from demo_date where date >= '3/1/2015' and date <=  '3/31/2015'.

Es ist sehr einfach ...... Es hat es getestet .....

pankaj
quelle
Dies beantwortet die Frage nicht ganz. Es fragt nach einem Monat, nicht nach einem Tag.
Curtis Yallop
Für Ihre März-Anfrage: Wenn das Datum "31.03.2015" um 13:00 Uhr ist, wird es nicht gefunden. Sie sollten <'01.04.2015' verwenden.
Curtis Yallop
Erwägen Sie auch die Verwendung des internationalen Datumsformats '2015-03-01'. In Kanada (und an vielen anderen Orten) ist TT / MM / JJJJ ein offizielles Format, wodurch beide Formate mehrdeutig und problematisch werden.
Curtis Yallop
Diese Antwort behandelt nicht 2 Tabellen, wie in der Frage angefordert.
Curtis Yallop
Ja, ich stimme zu, aber ich beweise nur die Lösung, nicht die internationale Lösung. Sie müssen eine Reihenfolge ändern ...
Pankaj