Wie vergleiche ich Zeitstempeldaten mit Nur-Datum-Parametern in MySQL?

88

Wie vergleiche ich in einer SQL-Anweisung ein als TIMESTAMP gespeichertes Datum mit einem Datum im Format JJJJ-MM-TT?

Ex.: SELECT * FROM table WHERE timestamp = '2012-05-05'

Ich möchte, dass diese Abfrage alle Zeilen mit Zeitstempel am angegebenen Tag zurückgibt, aber nur Zeilen mit Zeitstempel Mitternacht.

Vielen Dank

Michael
quelle

Antworten:

144

Mit der DATE()Funktion können Sie den Datumsanteil des Zeitstempels extrahieren:

SELECT * FROM table
WHERE DATE(timestamp) = '2012-05-05'

Wenn Sie jedoch einen Index für die Zeitstempelspalte haben, ist dies schneller, da ein Index für die Zeitstempelspalte verwendet werden kann, wenn Sie einen haben:

SELECT * FROM table
WHERE timestamp BETWEEN '2012-05-05 00:00:00' AND '2012-05-05 23:59:59'
Marcus Adams
quelle
5
Durch einen kleinen Test, den ich gerade lief, fand ich heraus, dass die Verwendung von ZWISCHEN um den Faktor 10X schneller ist. Nur zu
Ihrer Information
7
 WHERE cast(timestamp as date) = '2012-05-05'
Jürgen d
quelle
6

Wie von einigen vorgeschlagen, DATE(timestamp)wenden Sie bei der Verwendung eine Manipulation auf die Spalte an und können sich daher nicht auf die Indexreihenfolge verlassen.

Die Verwendung BETWEENwäre jedoch nur dann zuverlässig, wenn Sie die Millisekunden einbeziehen. Im Beispielzeitstempel BETWEEN '2012-05-05 00:00:00' AND '2012-05-05 23:59:59'schließen Sie Datensätze mit einem Zeitstempel zwischen 2012-05-05 23:59:59.001und aus 2012-05-05 23:59:59.999. Selbst diese Methode weist jedoch aufgrund der Genauigkeit der Datentypen einige Probleme auf. Gelegentlich werden 999 Millisekunden aufgerundet.

Das beste zu tun ist:

SELECT * FROM table
WHERE date>='2012-05-05' AND date<'2012-05-06'
Tom Kitson
quelle
5
SELECT * FROM table WHERE timestamp >= '2012-05-05 00:00:00' 
    AND timestamp <= '2012-05-05 23:59:59'
Cfreak
quelle
2

Verwenden Sie eine Konvertierungsfunktion von MYSQL:

SELECT * FROM table WHERE DATE(timestamp) = '2012-05-05' 

Das sollte funktionieren

adrien
quelle
1

Als ich dies recherchierte, dachte ich, es wäre schön, die ZWISCHEN-Lösung so zu ändern, dass ein Beispiel für ein bestimmtes nicht statisches / Zeichenfolgen-Datum, sondern ein variables Datum oder ein heutiges wie das heutige angezeigt wird CURRENT_DATE(). Dies wird den Index für die Spalte log_timestamp verwenden.

SELECT *
FROM some_table
WHERE
    log_timestamp
    BETWEEN 
        timestamp(CURRENT_DATE()) 
    AND # Adds 23.9999999 HRS of seconds to the current date
        timestamp(DATE_ADD(CURRENT_DATE(), INTERVAL '86399.999999' SECOND_MICROSECOND));

Ich habe die Sekunden / Mikrosekunden gemacht, um den Fall um 12 Uhr am nächsten Tag zu vermeiden. Sie können jedoch auch "INTERVAL" 1 TAG "über Vergleichsoperatoren durchführen, um einen leserfreundlicheren Nicht-ZWISCHEN Ansatz zu erhalten:

SELECT *
FROM some_table
WHERE
    log_timestamp >= timestamp(CURRENT_DATE()) AND
    log_timestamp < timestamp(DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY));

Beide Ansätze verwenden den Index und sollten VIEL schneller arbeiten. Beide scheinen gleich schnell zu sein.

asnyder
quelle
0

Wenn Sie SQL-Parameter zum Ausführen der Abfrage verwenden, ist dies hilfreich

SELECT * FROM table WHERE timestamp between concat(date(?), ' ', '00:00:00') and concat(date(?), ' ', '23:59:59')
devesh
quelle
0

Als ich Ihre Frage las, dachte ich, Sie wären in Oracle DB, bis ich das Tag 'MySQL' sah. Für Leute, die mit Oracle arbeiten, ist hier der Weg:

SELECT *
FROM table
where timestamp = to_timestamp('21.08.2017 09:31:57', 'dd-mm-yyyy hh24:mi:ss');
KeyMaker00
quelle
0

Verwenden

SELECT * FROM table WHERE DATE(2012-05-05 00:00:00) = '2012-05-05' 
Muhammad Fahad
quelle