2016-07-22 24 views
0

ich eine Abfrage lief, in der ich alle Aufträge finden wollte, die Juni gemacht wurden beginnend 1. Ursprünglich habe ich diesen Code:SQL-Datum Zeitformat auf der Suche gibt unterschiedliche Ergebnisse

select blah blah 
Where ORDERS.ORDER_DATE > '2016-05-31 23:59:59.999' 

Aber die Abfrage fehlgeschlagen um die am 1. Juni getätigten Bestellungen auszuwählen. Wenn ich den Code änderte:

Where ORDERS.ORDER_DATE > '2016-05-31 23:59:59.99' 

Ich bekam die Bestellungen vom 1. Juni. Der Unterschied ist der _2_ nines (.99) am Ende gegen _3_ nines (.999) in den Sekundenbruchteilen. Die Daten zeigen immer 3 Ziffern in den Brüchen. (Unsere Daten haben nur Nullen in den Sekundenbruchteilen "XX:XX:XX.000")

Was geht hier vor?

Antwort

0

Ich habe dieses Präzisionsproblem auch beim Erstellen von Datumsbereichen beobachtet, also entschied ich mich, es zu vereinfachen. Ich bin sicher, dass Sie dies bereits

betrachtet haben
Select ... ORDERS.ORDER_DATE >= '2016-06-01' 
0

für SQL-Server etwas mehr als 0,997 Millisekunden abrundet so ‚2016-05-31 23:59:59.999‘ ausgewertet wird, um die gleiche wie ‚2016-06-01 00:00:00.000‘. Verbinden Sie das mit Ihren Daten ist wahrscheinlich mehr von DATE und Sie würden nicht 2016-06-01 als Ergebnis erhalten.

Da

select blah blah 
Where ORDERS.ORDER_DATE > '2016-05-31 23:59:59.999' 

Würde als

select blah blah 
Where ORDERS.ORDER_DATE > '2016-06-01 00:00:00.000' 

So ausgewertet werden, wenn Ihr DATE nicht größer als 6/1 Sie das Ergebnis nicht

bekommen würde Warum die .99 Werke bacuase

select blah blah 
Where ORDERS.ORDER_DATE > '2016-05-31 23:59:59.99' 

wird als

select blah blah 
Where ORDERS.ORDER_DATE > '2016-05-31 23:59:59.990' 
+0

Quoten sind eine Million zu eins, aber nur um Mitternacht würde jede Transaktion wegfallen. Das heißt, danke für den 3-Millisekunden-Artikel. Genau das habe ich erlebt, bevor ich meinen Ansatz geändert habe. –

+0

ja um Mitternacht aber denken Sie darüber nach, wenn Sie einen DATETIME-Filter wie diesen verwenden, aber wirklich auf eine Spalte anwenden, die wirklich nur ein DATUM ist, was bedeutet, dass alles Mitternacht ist, dann schließen Sie tatsächlich jedes Ergebnis am 6/1 nicht nur Mitternacht aus.Dies ist ein Hauptgrund, nicht BETWEEN zu verwenden und ein> = (oder <=) auf einer Seite und nur das> oder Matt

+0

Die 3ms-Rundung ist nicht genau richtig: "datetime Werte werden auf Inkremente von .000, .003 oder .007 Sekunden gerundet, wie in der folgenden Tabelle gezeigt. " https://msdn.microsoft.com/en-us/library/ms187819.aspx Tatsächlich werden 4 von 10 auf .XX7 gerundet. Dies gilt nicht für "datetime2". – shawnt00

0

ausgewertet. Sie können nicht von Präzision ausgehen. Wenn Ihre Datumszeichenfolge in datetime konvertiert wird, wird sie als "2016-06-01" angezeigt. Ich nehme an, Ihre Bestellungen haben keine Zeitkomponente, also haben sie auch '2016-06-01', und da Sie > tun, vermissen Sie sie. Die datetime docs zeigen den Zeitbereich ist 00:00:00 through 23:59:59.997. Versuchen Sie, dies zu sehen:

CREATE TABLE test_date (dt datetime); 
insert into test_date values ('2016-05-31 23:59:59.999') 
select * from test_date 
-- result: 'June, 01 2016 00:00:00' 

Der richtige Weg, es zu tun wäre, um die genaue Startzeit zu verwenden, die Sie wünschen und >= nur nutzen, und verwenden Sie < für das Enddatum zusammen mit der genauen Startzeit für die nächste Periode .

select blah blah 
Where ORDERS.ORDER_DATE >= '2016-06-01' 

Dies wird unabhängig davon arbeiten, welche Datumsart Sie die ORDER_DATE verwenden für die Speicherung und wenn Sie Ihre Datenbank auf ein anderes System bewegen, die eine andere Präzision für den Zeitabschnitt eines Datetime-Objekt haben könnte.