MySQL SELECT WHERE Datum / Uhrzeit entspricht Tag (und nicht unbedingt Uhrzeit)


127

Ich habe eine Tabelle, die eine datetime-Spalte enthält. Ich möchte alle Aufzeichnungen eines bestimmten Tages unabhängig von der Uhrzeit zurückgeben. Mit anderen Worten, wenn meine Tabelle nur die folgenden 4 Datensätze enthält, werden nur der 2. und 3. zurückgegeben, wenn ich mich auf den 25.12.2012 beschränke.

2012-12-24 00:00:00
2012-12-25 00:00:00
2012-12-25 06:00:00
2012-12-26 05:00:00

Siehe Antwort von John Woo unter stackoverflow.com/questions/14769026/…
ekerner

Antworten:


326

Verwenden Sie NIEMALS einen Selektor wie DATE(datecolumns) = '2012-12-24'- es ist ein Leistungskiller:

  • Es wird DATE()für alle Zeilen berechnet , einschließlich derjenigen, die nicht übereinstimmen
  • Dadurch wird es unmöglich, einen Index für die Abfrage zu verwenden

Es ist viel schneller zu bedienen

SELECT * FROM tablename 
WHERE columname BETWEEN '2012-12-25 00:00:00' AND '2012-12-25 23:59:59'

Dies ermöglicht die Verwendung des Index ohne Berechnung.

BEARBEITEN

Wie Used_By_Already hervorhob, sind in der Zeit seit der ersten Antwort im Jahr 2012 Versionen von MySQL aufgetaucht, bei denen die Verwendung von '23: 59: 59 'als Tagesende nicht mehr sicher ist. Eine aktualisierte Version sollte lesen

SELECT * FROM tablename 
WHERE columname >='2012-12-25 00:00:00'
AND columname <'2012-12-26 00:00:00'

Der Kern der Antwort, dh die Vermeidung eines Selektors für einen berechneten Ausdruck, bleibt natürlich bestehen.


Ich wollte gerade kommentieren, dass die Lösung von a1ex07 nicht annähernd so gut zu sein scheint wie die anderen. Nachdem ich Ihren Beitrag gelesen habe, muss ich vielleicht mein Denken umkehren!
user1032531

2
Gerade auf zwei Servern getestet, ist das oben genannte VIEL (mindestens 10x) schneller als date () = '', insbesondere für große Tabellen. Danke
Zzapper

1
@KonradViltersten Ich habe die Abfrage sehr ausführlich formuliert, um sie besser lesbar zu machen und meinen Standpunkt zu verdeutlichen, ohne sie zu verfeinern. Die Antwort von a1ex07 hat die spärliche Syntax.
Eugen Rieck

9
@KonradViltersten - Besser noch : WHERE col >= '2012-12-25' AND col < '2012-12-25' + INTERVAL 1 DAY. Es vermeidet 0 Zeit und arbeitet für DATE, DATETIME, DATETIME(6), etc. Und beschäftigt sich mit Schalttag etc.
Rick James

1
'2012-12-25 23:59:59' ist als Tagesende NICHT GÜLTIG. Es war immer eine schlechte Idee und führt zu Fehlern bei Versionen von MySQL, die eine Genauigkeit von weniger als einer Sekunde unterstützen. Viel besser, den Ansatz von Rick James (oben) oder a1ex07 (andere Antwort) zu verwenden
Used_By_Already

34

... WHERE date_column >='2012-12-25' AND date_column <'2012-12-26'funktioniert möglicherweise besser (wenn Sie einen Index für date_column haben) als DATE.


1
Ich frage mich eigentlich, was schneller ist - dies oder die BETWEENLösung ... hat jemand eine Markierung?
jave.web

6
Es sollte kein Unterschied sein. BETWEENist nur eine Art zu schreiben field >= value1 and fied<= value2.
a1ex07

1
Beachten Sie Folgendes im MySQL-Handbuch: "Für beste Ergebnisse bei Verwendung von ZWISCHEN Datums- oder Zeitwerten verwenden Sie CAST (), um die Werte explizit in den gewünschten Datentyp zu konvertieren. Beispiele: Wenn Sie eine DATETIME mit zwei DATE-Werten vergleichen, konvertieren Sie das DATE Werte in DATETIME-Werte. Wenn Sie eine Zeichenfolgenkonstante wie '2001-1-1' im Vergleich zu einem DATE verwenden, wandeln Sie den String in ein DATE um. " Wenn sie nicht alle vom gleichen Typ sind, ist es am besten, sie explizit zu besetzen.
Techdude

21

Sie können verwenden %:

SELECT * FROM datetable WHERE datecol LIKE '2012-12-25%'

13
LIKE scheint so langsam zu sein wie DATE (datetimecol). Verwenden Sie besser die Lösung von Eugen oder a1ex07.
Marie Fischer

3
Es geht nicht immer um Geschwindigkeit. Also ich mag diese Lösung. Es ist viel besser lesbar.
Simon Hansen
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.