Jak porównać daty datownika z parametrem „tylko data” w MySQL?

88

Jak w instrukcji SQL porównać datę zapisaną jako TIMESTAMP z datą w formacie RRRR-MM-DD?

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

Chcę, aby to zapytanie zwróciło wszystkie wiersze z sygnaturą czasową w określonym dniu, ale zwraca tylko wiersze z sygnaturą czasową o północy.

dzięki

Michał
źródło

Odpowiedzi:

144

Możesz użyć tej DATE()funkcji, aby wyodrębnić część daty z sygnatury czasowej:

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

Chociaż, jeśli masz indeks w kolumnie timestamp, byłoby to szybsze, ponieważ mógłby wykorzystać indeks w kolumnie timestamp, jeśli taki masz:

SELECT * FROM table
WHERE timestamp BETWEEN '2012-05-05 00:00:00' AND '2012-05-05 23:59:59'
Marcus Adams
źródło
5
W trakcie małego testu, który właśnie przeprowadziłem, odkryłem, że użycie BETWEEN jest 10
krotnie
7
 WHERE cast(timestamp as date) = '2012-05-05'
juergen d
źródło
6

Jak sugerują niektórzy, używając, DATE(timestamp)stosujesz manipulację do kolumny i dlatego nie możesz polegać na kolejności indeksów.

Jednak użycie BETWEENbędzie niezawodne tylko wtedy, gdy uwzględnisz milisekundy. W przykładowym sygnaturze czasowej BETWEEN '2012-05-05 00:00:00' AND '2012-05-05 23:59:59'wykluczasz rekordy z datownikiem od 2012-05-05 23:59:59.001do 2012-05-05 23:59:59.999. Jednak nawet ta metoda ma pewne problemy ze względu na precyzję typów danych. Czasami 999 milisekund jest zaokrąglane w górę.

Najlepszą rzeczą do zrobienia jest:

SELECT * FROM table
WHERE date>='2012-05-05' AND date<'2012-05-06'
Tom Kitson
źródło
5
SELECT * FROM table WHERE timestamp >= '2012-05-05 00:00:00' 
    AND timestamp <= '2012-05-05 23:59:59'
Cfreak
źródło
2

Użyj funkcji konwersji MYSQL:

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

To powinno działać

adrien
źródło
1

Kiedy to badałem, pomyślałem, że fajnie byłoby zmodyfikować rozwiązanie BETWEEN, aby pokazać przykład dla konkretnej niestatycznej / łańcuchowej daty, ale raczej zmiennej daty lub dzisiejszej, takiej jak CURRENT_DATE(). To użyje indeksu na kolumnie log_timestamp.

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));

Zrobiłem sekundy / mikrosekundy, aby uniknąć przypadku o godzinie 12 rano następnego dnia. Możesz jednak również wykonać `` INTERVAL '1 DAY' 'za pomocą operatorów porównania, aby uzyskać bardziej przyjazne dla czytelnika podejście, które nie jest BETWEEN:

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

Oba te podejścia wykorzystają indeks i powinny działać DUŻO szybciej. Oba wydają się być równie szybkie.

asnyder
źródło
0

Jeśli używasz parametrów SQL do uruchomienia zapytania, byłoby to pomocne

SELECT * FROM table WHERE timestamp between concat(date(?), ' ', '00:00:00') and concat(date(?), ' ', '23:59:59')
devesh
źródło
0

Kiedy przeczytałem twoje pytanie, pomyślałem, że korzystasz z Oracle DB, dopóki nie zobaczyłem tagu „MySQL”. W każdym razie dla osób pracujących z Oracle jest sposób:

SELECT *
FROM table
where timestamp = to_timestamp('21.08.2017 09:31:57', 'dd-mm-yyyy hh24:mi:ss');
KeyMaker00
źródło
0

Posługiwać się

SELECT * FROM table WHERE DATE(2012-05-05 00:00:00) = '2012-05-05' 
Muhammad Fahad
źródło