T-SQL zwischen Datenüberschneidungen

8

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:

%Vor%

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!

    
ONDEV 25.03.2011, 14:45
quelle

5 Antworten

14

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.

    
GSerg 25.03.2011, 14:53
quelle
4

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:

%Vor%

Dann verwenden Sie @ToDate in Ihrer WHERE -Klausel in der BETWEEN -Spalte auf die übliche Weise.

    
DOK 25.03.2011 14:55
quelle
3

'12 / 01/2010 'bedeutet '12 / 01/2010 00:00:00' und '12 / 31/2010 'bedeutet '12 / 31/2010 00:00:00'. Aus diesem Grund werden Datums- und Uhrzeitwerte, die später am Tag des 31.12.2010 fallen, von Ihren Abfrageergebnissen ausgeschlossen.

    
Greg 25.03.2011 14:53
quelle
2

Was wäre Ihr erwartetes Ergebnis, wenn ich das tun würde

%Vor%

Genau: 12-31-2010 00:00:00

Warum sollten Sie also erwarten, dass es als Argument für eine Abfrage anders ist?

    
Pleun 25.03.2011 14:52
quelle
1

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

%Vor%     
Lieven Keersmaekers 25.03.2011 14:52
quelle

Tags und Links