T-SQL Zwischen Datumsangaben Verwirrung
Ich arbeite mit T-SQL in SQL Server 2000 und ich habe eine Tabelle TRANSACTIONS
hat eine Datum-Spalte TRANDATE
definiert, wie DateTime, unter vielen anderen Spalten sind nicht relevant für diese Frage..
Die Tabelle wird aufgefüllt, mit den Transaktionen über zahlreiche Jahre. Ich lief in code, das testen, das hat mich verwirrt. Es ist eine einfache SELECT
wie diese:
SELECT TRANDATE, RECEIPTNUMBER FROM TRANSACTIONS WHERE TRANDATE BETWEEN '12/01/2010' and '12/31/2010' ORDER BY TRANDATE
und seine-nicht wieder zwei Reihen von Daten, die ich kenne, sind in dieser Tabelle.
Mit der Aussage oben, die Letzte Zeile seiner Rückkehr, im Auftrag, hat eine TRANDATE
von:
2010-12-31 00:00:00.000
Wenn ich ändern Sie die Anweisung wie unten, bekomme ich die beiden zusätzlichen Zeilen für Dezember 2010 sind in dieser Tabelle:
SELECT TRANDATE, RECEIPTNUMBER FROM TRANSACTIONS WHERE TRANDATE BETWEEN '12/01/2010 00:00:00' and '12/31/2010 23:59:59' ORDER BY TRANDATE
Habe ich versucht heraus zu finden, warum die BETWEEN
Betreiber nicht enthalten ALLE Zeilen für die 24 Stunden in 12/31/2010 bei der Nutzung der ersten SELECT
vor. Und wieso braucht es die ausdrückliche Stunden Hinzugefügt, um die SELECT
Aussage als in die zweite, geänderte Anweisung, um es zu bekommen, ziehen Sie die richtige Anzahl von Zeilen aus?
Ist es aufgrund der Art und Weise TRANDATE
ist definiert als "DATETIME
"?
Basierend auf diesem Ergebnis, ich denke, dass werde müssen gehen durch alle diese alt-Codes, da diese BETWEEN
Betreiber übersät sind, während das alte system, und es scheint, wie die nicht ziehen Sie alle Daten richtig. Ich wollte nur eine Klarstellung einige Leute ersten. Danke!
'12/31/2010 23:59:59'
noch vermissen würde mal zwischen12/31/2010 23:59:59
und12/31/2010 23:59:59:997
nicht verwendenbetween
für datetimes verwenden>= and <
statt.- Danke. Und danke an alle anderen. Vor allem @GSerg, der hat im Grunde die Antwort auf meine Frage unten. Ich kann upvote, so scheint es, bis ich 15 Punkte, so dass ist, warum Sie alle nicht sehen, jeder (von mir). Aber jetzt verstehe ich die Basis auf alle, die Antworten. Danke. Ich habe einige Arbeit zu tun! 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ein Datum ist ein Zeitpunkt, keine Zeitspanne.
'12/31/2010'
ist ein Punkt, den auch. Nämlich, es ist die Mitternacht des 31.Alles, was nach diesem Punkt wird ignoriert.
Das ist genau das Verhalten, die Sie möchten (auch wenn Sie noch nicht realisiert, dass noch).
Glaube nicht, dass, wenn Sie wählen, um das auslassen der Teil der Zeit, es wird automatisch davon ausgegangen, dass
"any"
. Es geht um"all zeroes"
, das heißt, die Mitternacht.Wenn Sie wollen, zu zählen, den ganzen Tag in deine Abfrage ohne Angabe von
23:59:59
(die durch die Art und Weise, schließt der letzten Sekunde des Tages, zwischen den moment23:59:59
des aktuellen Tages und der moment00:00:00
des nächsten Tages), können Sie das entweder durch eine strikte Ungleichungen (>
,<
) begrenzt durch die ersten Punkte der Zeit, die Sie nicht wollen:oder durch den Vergleich von Datum-Werten gecastet zu
DATE
:(es ist okay, um diese Art der Besetzung in einem
WHERE
Klausel, es ist sargable).Als Sie entdeckt haben, wenn Sie nicht geben Sie eine Zeit, wenn die Eingabe ein Datum ist, wird standardmäßig Mitternacht am morgen des Datums. So 12/31/2010 Stoppt um Mitternacht, wenn der Tag beginnt.
Erhalten Sie alle Termine für 12/31/2010, können Sie entweder geben Sie die Zeit, wie Sie das getan haben, oder fügen Sie einen Tag, um das Enddatum. Ohne Zeit, 1/1/2011 endet um Mitternacht auf 12/31/2010. So könnten Sie
BETWEEN 12/1/2010 AND 1/1/2011
. Sie könnenDATEADD
hinzufügen, um den Tag in Ihrem SQL, wenn das macht es einfacher.Gibt es einige Gefahren in sich, dass der zweite Ansatz für das hinzufügen einer Tag. Erhalten Sie alle Datensätze für 1/1/2011, die Durchführung der Zeit von 00:00:00.
Hier ist eine Möglichkeit, durchführen die
DATEADD
:Dann verwenden Sie
@ToDate
in IhremWHERE
- Klausel in derBETWEEN
Satz in der üblichen Weise.'12/01/2010' bedeutet '12/01/2010 00:00:00' und '12/31/2010' bedeutet '12/31/2010 00:00:00'. Dies ist der Grund, warum datetime-Werte fallen später an dem Tag, an 12/31/2010 sind ausgeschlossen aus der Abfrage Ergebnisse.
Was wäre das erwartete Ergebnis wäre, wenn ich dies tun
Genau: 12-31-2010 00:00:00
Also, warum würden Sie erwarten, dass es, anders zu sein als argument für eine Abfrage?
Haben Sie Art beantwortet Ihre eigene Frage bereits. Was Sie beobachtet haben ist, wie SQL Server arbeitet.
Wenn es ist eine Bestätigung, die Sie brauchen, diese MSDN-Dokument hat Folgendes zu sagen über es
Bearbeiten
Als für Ihren Kommentar, ein datetime ist im wesentlichen eine floating-point-Wert.
Folgende Skript zeigt, welche zahlen der SQL Server funktioniert mit.
40541.9749 (12/31/2010 23:23:59) kann nicht aufgenommen werden, wenn Ihre Obere Schranke ist 40541 (12/31/2010)