MySQL vergleicht die DATE-Zeichenfolge mit der Zeichenfolge aus dem DATETIME-Feld

88

Ich habe eine Frage: Ist es möglich, aus einer MySQL-Datenbank auszuwählen, indem eine DATE-Zeichenfolge "2010-04-29" mit Zeichenfolgen verglichen wird, die als DATETIME (2010-04-29 10:00) gespeichert sind?

Ich habe eine Datumsauswahl, die Daten filtert, und ich möchte die Tabelle nach dem Feld DATETIME wie folgt abfragen:

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

... und ich möchte die Zeile mit dem DATETIME-Wert "2010-04-29 10:00" erhalten.

Irgendwelche Vorschläge? Vielen Dank.

Manny Calavera
quelle

Antworten:

159

Verwenden Sie Folgendes:

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

Nur als Referenz habe ich eine 2-Millionen-Datensatztabelle, ich habe eine ähnliche Abfrage ausgeführt. Die Antwort von Salils dauerte 4,48 Sekunden, die oben genannte Antwort 2,25 Sekunden.

Wenn der Tisch also GROSS ist, würde ich dies eher vorschlagen.

David
quelle
7
Die erste Antwort ist so langsam, weil sie vor dem Vergleich jedes Datum und jede Uhrzeit in eine Zeichenfolge formatieren muss. Ihr ist besser, weil es direkt nur den
Datumsteil
1
Wenn die Leistung ein Problem darstellt, kann es sinnvoll sein, Datums- und Uhrzeitteil getrennt zu speichern, damit ein INDEX auf dem Datumsteil platziert werden kann.
Thijs Riezebeek
1
Diese Abfrage kann den Index nicht verwenden, wenn sie startTimeindiziert ist.
Zamrony P. Juhara
39

Wenn Sie alle Zeilen auswählen möchten, in denen der DATE-Teil einer DATETIME-Spalte mit einem bestimmten Literal übereinstimmt, können Sie dies nicht folgendermaßen tun:

WHERE startTime = '2010-04-29'

weil MySQL ein DATE und ein DATETIME nicht direkt vergleichen kann. Was MySQL macht, erweitert das angegebene DATE-Literal um die Zeit '00: 00: 00 '. So wird Ihr Zustand

WHERE startTime = '2010-04-29 00:00:00'

Sicher nicht was du willst!

Die Bedingung ist ein Bereich und sollte daher als Bereich angegeben werden. Es gibt mehrere Möglichkeiten:

WHERE startTime BETWEEN '2010-04-29 00:00:00' AND '2010-04-29 23:59:59'
WHERE startTime >= '2010-04-29' AND startTime < ('2010-04-29' + INTERVAL 1 DAY)

Es gibt eine winzige Möglichkeit, dass die erste falsch ist - wenn Ihre DATETIME-Spalte eine Auflösung von weniger als einer Sekunde verwendet und ein Termin um 23:59:59 + epsilon vorliegt. Generell schlage ich vor, die zweite Variante zu verwenden.

Beide Varianten können einen Index für startTime verwenden, der wichtig wird, wenn die Tabelle wächst.

XL_
quelle
9
Davids Version ist nicht gut, sie kann keine Indizes verwenden. Um einen Index zu verwenden, müssen Sie Filter auf der Säule direkt, nicht auf ein Ergebnis einer Funktion ( date(), year(), datediff()oder ähnliche)
Marki555
Ich habe gesucht, wie MySQL das Datum in Datum / Uhrzeit konvertiert, danke für das Löschen, das es hinzufügt 00:00:00. Jetzt machen meine Ergebnisse Sinn
Buchhalter م
1
Dies ist die richtige schnelle Lösung im Vergleich zu anderen Antworten, die keinen Index verwenden können, falls verfügbar
Zamrony P. Juhara
23
SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"

ODER

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'
Salil
quelle
22
Dies ist eine schreckliche Frage. Vermeiden Sie dies um jeden Preis. Wenn es einen Index für startTime gibt, kann er von dieser Abfrage nicht verwendet werden, da eine Funktion auf die Spalte angewendet wird, anstatt sie direkt zu verwenden. Das bedeutet, dass für jede solche Abfrage ein vollständiger Tabellenscan erforderlich ist. Bei einer großen Tabelle bedeutet dies eine extrem langsame Abfrage.
Steveayre
Ich stimme zu, seine Antwort ist falsch - die richtige Antwort wurde von David unten gepostet.
mindplay.dk
1
Bitte benutzen Sie die Antwort von David, weil es viel schneller geht. Dieser ist gültig, aber nicht gut für die Geschwindigkeit ...
xarlymg89
1
@ CarlosAlbertoMartínezGadea Diese Version ist langsam, da jeder Wert vor dem Vergleich als Zeichenfolge formatiert werden muss ... Davids Version benötigt ihn nicht, kann jedoch keine Indizes verwenden und ist daher nicht optimal. Siehe Antwort von XL_ für eine Version, die Index verwenden kann. Leider gibt es keinen besseren Weg, um es richtig in
MySQL
Ich habe diese Antwort abgelehnt, weil die Abfrage keinen Index verwenden kann, während die Antwort von @ XL_ dies tut.
Pedromanoel
2
SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')

Dies für das Datum / Uhrzeit-Format in MySQL mit DATE_FORMAT(date,format).

RT
quelle
1
SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29';

Es hilft, Sie können die Werte wie DATEvor dem Vergleich konvertieren .

Sarath
quelle
0

Sie können das Feld DATETIME wie folgt in DATE umwandeln:

SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'

Das ist sehr effizient.

SGAmpere
quelle
Nein, es ist auch nicht effizient. Dies wird nicht in der Lage sein, Index zu verwenden, wenn startTimeindiziert ist
Zamrony P. Juhara
-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

Sie können auch Vergleichsoperatoren für MySQL-Daten verwenden, wenn Sie nach oder vor etwas suchen möchten. Dies liegt daran, dass sie so geschrieben sind (größter bis kleinster Wert mit führenden Nullen), dass eine einfache Zeichenfolgensortierung sie korrekt sortiert.

Fletcher Moore
quelle