Einschränkung auf einen Datumsbereich mit Genauigkeit im MS SQL / SQL Server 2005
Möchte ich einen Bericht so einschränken, um Datensätze zurückzugeben, die von Datum A bis Datum B Dies ist, was ich Tue:
declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections
where date between @startDate and @endDate
... das wurde mir gesagt zurückgegebenen Datensätze von 12 am Jan 1. durch 11:59 pm 31 März (midnight, ist die Standardeinstellung, wenn keine Zeit angegeben wurde). Aber ich bemerkte eine Diskrepanz, die ist, wenn ein Datensatz hat eine Zeit von 00:00:00, dass es Teil dieser Gruppe.
Gibt es einen genauer Weg, dies zu tun, so wird es wieder genau den Datumsbereich, die ich will?*
Ich habe versucht, unter Verwendung der Zeit:
declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008 00:00:00'
set @endDate = '04/01/2008 11:59:59'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections
where date between @startDate and @endDate
... aber ich bemerkte etwas wackelig: SQL Server RUNDEN die Hundertstel-Sekunde bis um die Hälfte. Also ich bekomme das 1. April ist record (ha! April Fool ' s aufnehmen! grr), wenn ich jedes mal später als 11:59:29. Warum ist das so?
- (Ich bin mir sicher es ist. Ich bin neu in diesem. Vielen Dank für Ihre Hilfe!!!)
- Danke!!! Dies hilft eine Menge. @ G-Mastros: Es ist SmallDateTime -- danke für die Erklärung, das Verhalten dieses Datentyps!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Immer gibt es die einfache option:
Ich vermute, dass die Datum-Spalte in view_Inspections ist ein SmallDateTime-Datentyp. Dieser Datentyp hat 1 minute Genauigkeit, die erklärt Ihre unerwartete Ergebnisse (Rundung die Sekunden auf die nächste minute).
Die Methode Roland Shaw schlägt, ist der beste Weg, um ändern Sie Ihre Abfrage, um Ihren Anforderungen gerecht.
Den ZWISCHEN-operator ist inclusive, das ist, warum Sie sehen die Ergebnisse, die Sie in Ihrem ersten Abfrage. Die Rundung, die Sie sehen in Ihrer zweiten Abfrage wird davon abhängig sein, was genau datetime-Datentyp Sie verwenden in Ihrer Tabelle. (BTW, ich glaube, du bist verwirrend Sekunden mit Hundertstel Sekunden). Wie es aussieht, bist du wahrscheinlich mit einem smalldatetime in der Tabelle, in dem Fall ist die Zeit, gerundet auf die nächste minute.
Wenn Ihre Tabelle mit datetime, versuchen Sie explizit konvertieren Sie Ihre @startDate und @endDate DATETIME-Werte (CAST(@endDate AS DATETIME)).
Einen schnellen Hinweis... auch für DATETIME-Werte, SQL-Server nur genau die 3/100ths von einer Sekunde, also 11:59:59.999 verwendet werden abgerundete bis zu 12:00:00.000.
Haben Sie grundsätzlich drei Möglichkeiten:
1) ZWISCHEN CAST('01/01/2008 00:00:00.000' AS DATETIME) UND CAST('03/31/2008 12:59:59.997' AS DATETIME)
2) JAHR(my_date) = 2008 UND MONAT(my_date) ZWISCHEN 1 UND 3
3) my_date >= CAST('01/01/2008 00:00:00.000' AS DATETIME) UND my_date < CAST('04/01/2008 00:00:00.000' AS DATETIME)
Die erste Methode ist nicht sehr intuitiv und fehleranfällig ist, meiner Meinung nach. Die zweite Methode tötet Leistung, da die Indizes nicht verwendet werden können, und es wird viel komplizierter, wenn Sie haben können Suche, die sich über Jahre oder Anfang/Ende in der Mitte der Monate. Die Dritte Methode, die Rowland vorgeschlagen, ist das beste, denke ich.
Einfach versuchen, das entfernen der Zeit aus dem Feld Datum etwa so:
Diesem alles zurückgeben, was von
01/01/2008 00:00:00
zu04/01/2008 11:59:59.999
.Wenn Sie nicht möchten, dass
04/01
enthalten, ändern Sie Ihre end-Datum03/31/2008
.Ihre beste Lösung ist, erstellen Sie einfach eine BIGINT(10) Feld, das als "julian" und speichern es im Format YYYYMMDD.
Führen Sie dann die Abfrage
wo julian >= '20120103' UND julian <= '20120203'