Ich arbeite mit T-SQL in SQL Server 2000 und ich habe eine Tabelle TRANSACTIONS
, die eine Datumsspalte TRANDATE
definiert als DateTime unter vielen anderen Spalten hat, die für diese Frage irrelevant sind.
Die Tabelle enthält Transaktionen mit vielen Jahren. Ich bin auf Code gestoßen, Test, das hat mich verwirrt. Es gibt ein einfaches SELECT
, wie folgt:
und es gibt keine zwei Datenzeilen zurück, von denen ich weiß, dass sie sich in dieser Tabelle befinden.
Mit der obigen Anweisung hat die letzte Zeile, die in der Reihenfolge zurückgegeben wird, TRANDATE
von:
2010-12-31 00: 00: 00.000
Wenn ich die Anweisung wie unten beschrieben ändere, erhalte ich die zusätzlichen zwei Zeilen für Dezember 2010, die in dieser Tabelle enthalten sind:
%Vor% Ich habe versucht herauszufinden, warum der BETWEEN
-Operator nicht alle Zeilen für die 24 Periode in 31.12.2010 enthält, wenn die erste SELECT
oben verwendet wird. Und warum müssen die expliziten Stunden der Anweisung SELECT
wie in der zweiten, modifizierten Anweisung hinzugefügt werden, damit sie die richtige Anzahl Zeilen herauszieht?
Liegt es daran, dass TRANDATE
als " DATETIME
" definiert ist?
Aufgrund dieses Ergebnisses denke ich, dass ich all diesen alten Code durchgehen muss, weil diese BETWEEN
-Operatoren in diesem alten System verstreut sind und es so aussieht, als würde er nicht alle Daten richtig erfassen. Ich wollte nur von einigen Leuten zuerst geklärt werden. Danke!
Ein Datum ist ein Zeitpunkt, keine Zeitspanne.
'12/31/2010'
ist auch ein Punkt. Nämlich, es ist die Mitternacht des 31. Dezembers.
Alles, was nach diesem Punkt passiert ist, wird ignoriert
Das ist genau das Verhalten, das Sie wollen (auch wenn Sie das noch nicht erkannt haben).
Denken Sie nicht, dass, wenn Sie den Zeitteil weglassen, magisch angenommen wird, dass er "any"
ist. Es wird "all zeroes"
sein, also Mitternacht.
Wenn Sie bei der Eingabe eines Datums keinen Zeitpunkt angegeben haben, wird standardmäßig auf Mitternacht am Morgen des Datums festgelegt. So 31/12/2010 stoppt um Mitternacht, wenn dieser Tag beginnt.
Um alle Daten für den 31.12.2010 zu erhalten, können Sie entweder die Uhrzeit angeben , wie Sie es getan haben, oder einen Tag bis zum Enddatum hinzufügen . Ohne Zeit endet der 01.01.2011 um Mitternacht am 31.12.2010. Also könntest du BETWEEN 12/1/2010 AND 1/1/2011
machen. Sie können DATEADD
verwenden, um den Tag in Ihrem SQL hinzuzufügen, wenn das einfacher ist.
Es besteht ein gewisses Risiko in diesem zweiten Ansatz, einen Tag hinzuzufügen. Sie erhalten alle Datensätze für 1/1/2011, die die Zeit von 00:00:00 enthalten.
Hier ist eine Möglichkeit, DATEADD
auszuführen:
Dann verwenden Sie @ToDate
in Ihrer WHERE
-Klausel in der BETWEEN
-Spalte auf die übliche Weise.
Sie haben Ihre eigene Frage bereits beantwortet. Was Sie beobachtet haben, ist die Funktionsweise von SQL Server.
Wenn es eine Bestätigung ist, die Sie benötigen, MSDN-Dokument hat folgendes zu sagen
Wenn der Zeitteil nicht spezifiziert ist, dann Standardeinstellung ist 12:00 Uhr. Beachten Sie, dass eine Zeile das enthält einen Zeitteil, der ist nach 12:00 Uhr auf 1998-0105 würde von dieser Abfrage nicht zurückgegeben werden, weil es fällt außerhalb des Bereichs.
Bearbeiten
Wie bei Ihrem Kommentar ist ein datetime im Wesentlichen ein Gleitkommawert.
Folgendes Skript zeigt, mit welchen Zahlen SQL Server arbeitet.
40541.9749 (31.12.2010 23:23:59) kann nicht aufgenommen werden, wenn Ihre obere Grenze 40541 (31.12.2010) ist
Tags und Links tsql sql-server-2000 between