Ich habe eine Frage wie diese:
SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'
Dies liefert jedoch keine Ergebnisse, obwohl Daten für den 1. Platz vorliegen.
created_at
sieht aus wie 2013-05-01 22:25:19
, ich vermute, es hat mit der Zeit zu tun? Wie konnte das gelöst werden?
Es funktioniert gut, wenn ich größere Datumsbereiche mache, aber es sollte (inklusive) auch mit einem einzigen Datum funktionieren.
Es ist inklusive. Sie vergleichen Datumsangaben mit Datumsangaben. Das zweite Datum wird als Mitternacht interpretiert wenn der Tag beginnt.
Eine Möglichkeit, dies zu beheben, ist:
SELECT *
FROM Cases
WHERE cast(created_at as date) BETWEEN '2013-05-01' AND '2013-05-01'
Eine andere Möglichkeit, dies zu beheben, besteht in expliziten binären Vergleichen
SELECT *
FROM Cases
WHERE created_at >= '2013-05-01' AND created_at < '2013-05-02'
Aaron Bertrand hat einen langen Blogeintrag zu Terminen ( hier ), in dem er diese und andere Termine behandelt.
Es wurde angenommen, dass die zweite Datumsreferenz in der BETWEEN
-Syntax magisch als "Ende des Tages" betrachtet wird, aber dies ist nicht wahr.
das war erwartet worden:
SELECT * FROM-Fälle WO erstellt_at ZWISCHEN der Anfang von "2013-05-01" UND das Ende von '2013-05-01'
was aber wirklich passiert ist folgendes:
SELECT * FROM-Fälle WO wurde zwischen 2013-05-01 erstellt 00: 00: 00 + 00000'UND' 2013-05-01 00: 00: 00 + 00000'
Welches wird das Äquivalent von:
SELECT * FROM-Fälle, in denen WHERE_AT = '2013-05-01 00: 00: 00 + 00000'
Das Problem ist eine der Wahrnehmungen/Erwartungen bezüglich BETWEEN
, wobei do sowohl den unteren Wert als auch die oberen Werte des Bereichs enthält, aber nicht ein Datum magisch als "Anfang" oder "das Ende von".
BETWEEN
sollte beim Filtern nach Datumsbereichen vermieden werden.
Immer stattdessen >= AND <
verwenden
SELECT * FROM-Fälle WHERE (Created_at > = '20130501' UND hergestellt in < '20130502')
die Klammern sind hier optional, können jedoch bei komplexeren Abfragen wichtig sein.
Sie müssen eine der beiden folgenden Optionen ausführen:
between
-Bedingung ein: ... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59'
(nicht empfohlen ... siehe letzten Absatz)between
. Beachten Sie, dass Sie dem zweiten Wert dann einen Tag hinzufügen müssen: ... where (created_at >= '2013-05-01' and created_at < '2013-05-02')
Meine persönliche Präferenz ist die zweite Option. Aaron Bertrand hat eine sehr klare Erklärung warum es verwendet werden sollte.
Ich finde, dass die beste Lösung zum Vergleichen eines datetime-Feldes mit einem Datumsfeld die folgende ist:
DECLARE @StartDate DATE = '5/1/2013',
@EndDate DATE = '5/1/2013'
SELECT *
FROM cases
WHERE Datediff(day, created_at, @StartDate) <= 0
AND Datediff(day, created_at, @EndDate) >= 0
Dies ist gleichbedeutend mit einer inklusiven Anweisung zwischen den Anweisungen, da sowohl das Start- und Enddatum als auch die dazwischen liegenden enthalten sind.
Verwenden Sie einfach den Zeitstempel als Datum:
SELECT * FROM Cases WHERE date(created_at)='2013-05-01'
cast(created_at as date)
Das funktioniert nur in 2008 und neueren Versionen von SQL Server
Wenn Sie eine ältere Version verwenden, verwenden Sie
convert(varchar, created_at, 101)
Sie können die Funktion date()
verwenden, die das Datum aus einer Datumszeit extrahiert und das Ergebnis als Inklusivdatum ausgibt:
SELECT * FROM Cases WHERE date(created_at)='2013-05-01' AND '2013-05-01'