Abfrage zum Vergleichen von Daten in SQL

84

Ich habe eine Tabelle mit Daten, die alle im Monat November passiert sind. Ich habe diese Abfrage geschrieben

select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where 
created_date <= '2013-04-12'

Diese Abfrage sollte alles zurückgeben, was im Monat 11 (November) passiert ist, da es vor dem Datum '2013-04-12' (im Dezember) passiert ist.

Aber es ist die Rückkehr nur Termine, die weniger in Tagen passiert als 04 (2013- 04 -12)

Könnte es sein, dass es nur den Tagesteil vergleicht? und nicht das ganze Datum?

Wie kann ich das beheben?

Erstellungsdatum ist vom Typ Datum

Das Datumsformat ist standardmäßig JJJJ-TT-MM

HelpASisterOut
quelle
1
Sie vergleichen Daten mit Zeichenfolgen, nicht Daten mit Daten
Panagiotis Kanavos
4
Vielleicht denkt es 2013-04-12? ist der 12. April? Oder ist vielleicht created_dateeine Zeichenfolge und kein Datum?
jpw
Schauen Sie sich Cast & Convert im T-SQL-Handbuch an und verwenden Sie die entsprechende Konvertierung für Ihr Gebietsschema
Steve
3
Keine Notwendigkeit zu gießen, verwenden Sie einfach das invariante Format '20130412'
Panagiotis Kanavos
1
Anstatt dann eine Zeichenfolge mit dem Datum zu senden, erstellen Sie eine parametrisierte Abfrage und übergeben Sie das Datum als datumstypisierten Parameter. Übrigens, welche Version von SQL Server verwenden Sie? DATE wurde in SQL Server 2008 hinzugefügt.
Panagiotis Kanavos

Antworten:

84

Verwenden Sie anstelle von '2013-04-12', dessen Bedeutung von der lokalen Kultur abhängt, '20130412', das als kulturinvariantes Format anerkannt ist.

Wenn Sie mit 4. Dezember vergleichen wollen th , sollten Sie ‚20131204‘ schreiben. Wenn Sie mit dem 12. April vergleichen möchten th , sollten Sie ‚20130412‘ schreiben.

Der Artikel Schreiben internationaler Transact-SQL-Anweisungen aus der SQL Server-Dokumentation erläutert, wie Anweisungen geschrieben werden, die kulturinvariant sind:

Anwendungen, die andere APIs oder Transact-SQL-Skripte, gespeicherte Prozeduren und Trigger verwenden, sollten die nicht getrennten numerischen Zeichenfolgen verwenden. Zum Beispiel yyyymmdd als 19980924.

BEARBEITEN

Da Sie ADO verwenden, besteht die beste Option darin, die Abfrage zu parametrisieren und den Datumswert als Datumsparameter zu übergeben. Auf diese Weise vermeiden Sie das Formatproblem vollständig und profitieren auch von den Leistungsvorteilen parametrisierter Abfragen.

AKTUALISIEREN

Um das ISO 8601-Format in einem Literal verwenden zu können, müssen alle Elemente angegeben werden. Zitat aus dem Abschnitt ISO 8601 der datetime-Dokumentation

Um das ISO 8601-Format zu verwenden, müssen Sie jedes Element im Format angeben. Dies schließt auch das T, die Doppelpunkte (:) und den Punkt (.) Ein, die im Format angezeigt werden.

... der Bruchteil der zweiten Komponente ist optional. Die Zeitkomponente wird im 24-Stunden-Format angegeben.

Panagiotis Kanavos
quelle
@undy nicht genau, das ISO8601-Format enthält das Zeitelement . Oder wie die Dokumente sagen , To use the ISO 8601 format, you must specify each element in the format. This also includes the T.
Panagiotis Kanavos
1
Es tut mir leid, dass ich unklar war. Mein Punkt war, dass ISO8601 die Reihenfolge genau so definiert, wie Sie es beschrieben haben: JJJJ-MM-TT oder kurz JJJJMMTT. In den Dokumenten heißt es jedoch auch: "datetime ist nicht ANSI- oder ISO 8601-kompatibel." Die ISO selbst würde keinen Zeitteil erfordern.
Andy
Was Sie meinen, ändert nichts an der Tatsache, dass YYYY-MM-DDes nicht als ISO 8601 anerkannt ist. Die Zeitteile sind erforderlich. Nennen wir es die Seltsamkeit von T-SQL, wenn Sie so wollen, oder die unvollständige Implementierung. Es kann sogar sein, dass dies von Sybase
Panagiotis Kanavos
32

Versuchen Sie es so

select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where 
created_date <= '2013-12-04'
Nithesh Narayanan
quelle
6
Kulturspezifisches Format. Ist das der 12. April oder der 4. Dezember? Das durch
Striche
1
Was passiert also, wenn Sie Daten von internationalen Kunden speichern müssen? Oder stammt das Datum von einem Webbrowser, der der Benutzerkultur folgt ? Die Richtlinien existieren aus einem Grund, und indem Sie einfach NICHT das falsche Format verwenden, vermeiden Sie alle Fehler
Panagiotis Kanavos
1
@Nithesh Dies ist der 12. April
HelpASisterOut
18
@PanagiotisKanavos Das strichgetrennte Format ist das internationale Format seit der Veröffentlichung von ISO 8601 im Jahr 1988. Andere Formate werden nicht empfohlen und lächerlich gemacht . Selbst der Artikel "Write International Transact-SQL Statements", den Sie veröffentlicht haben, identifiziert "yyyymmdd " niemals als einen "internationalen" Standard.
Jesse Webb
2
Das Hinzufügen von einfachen Anführungszeichen um das Datum hat dies für mich behoben. Verwendete das Format 19.02.2015. Geändert zu '19.02.2015' und es fing an zu funktionieren. Danke für die einfache Idee.
Ethan Turk
10

Wenn Sie nur mit dem Datumsbereich vergleichen, funktioniert die Konvertierung in Datum (nicht Datum / Uhrzeit )

select id,numbers_from,created_date,amount_numbers,SMS_text 
 from Test_Table
 where 
 created_date <= convert(date,'2013-04-12',102)

Diese Konvertierung gilt auch für die Verwendung der Funktion GetDate ()

Bimzee
quelle
4

Sie setzen <=und es wird auch das angegebene Datum fangen. Sie können es <nur durch ersetzen .

Kuzgun
quelle
2

Bitte versuchen Sie es mit der folgenden Abfrage

select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where 
convert(datetime, convert(varchar(10), created_date, 102))  <= convert(datetime,'2013-04-12')
Naresh Pansuriya
quelle
0

Das Datumsformat ist JJJJ-MM-TT. Die obige Abfrage sucht also nach Datensätzen, die älter als 12Apr2013 sind

Schlagen Sie vor, eine schnelle Überprüfung durchzuführen, indem Sie die Datumszeichenfolge auf '2013-04-30' setzen. Wenn kein SQL-Fehler vorliegt, wird das Datumsformat auf JJJJ-MM-TT bestätigt.

Bowie
quelle
0

Versuchen Sie, "#" vor und nach dem Datum zu verwenden, und achten Sie auf das Datumsformat Ihres Systems. vielleicht "JJJJMMTT O JJJJ-MM-TT O MM-TT-JJJJ O VERWENDUNG '/ O \'"

Ex:

 select id,numbers_from,created_date,amount_numbers,SMS_text 
 from Test_Table
 where 
 created_date <= #2013-04-12#
Ren Marín
quelle