Как сравнить даты с метками времени с параметром только даты в MySQL?

88

Как в операторе SQL сравнить дату, сохраненную как TIMESTAMP, с датой в формате ГГГГ-ММ-ДД?

Пример: SELECT * FROM table WHERE timestamp = '2012-05-05'

Я хочу, чтобы этот запрос возвращал все строки с меткой времени в указанный день, но он возвращал только строки с меткой времени в полночь.

Благодарность

Майкл
источник

Ответы:

144

Вы можете использовать эту DATE()функцию для извлечения части даты из метки времени:

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

Though, if you have an index on the timestamp column, this would be faster because it could utilize an index on the timestamp column if you have one:

SELECT * FROM table
WHERE timestamp BETWEEN '2012-05-05 00:00:00' AND '2012-05-05 23:59:59'
Marcus Adams
источник
5
Through a small test I just ran, I found using BETWEEN to be faster by a factor of 10X Just FYI
DarbyM
6

As suggested by some, by using DATE(timestamp) you are applying manipulation to the column and therefore you cannot rely on the index ordering.

However, using BETWEEN would only be reliable if you include the milliseconds. In the example timestamp BETWEEN '2012-05-05 00:00:00' AND '2012-05-05 23:59:59' you exclude records with a timestamp between 2012-05-05 23:59:59.001 and 2012-05-05 23:59:59.999. However, even this method has some problems, because of the datatypes precision. Occasionally 999 milliseconds is rounded up.

The best thing to do is:

SELECT * FROM table
WHERE date>='2012-05-05' AND date<'2012-05-06'
Tom Kitson
источник
5
SELECT * FROM table WHERE timestamp >= '2012-05-05 00:00:00' 
    AND timestamp <= '2012-05-05 23:59:59'
Cfreak
источник
2

Use a conversion function of MYSQL :

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

This should work

adrien
источник
1

As I was researching this I thought it would be nice to modify the BETWEEN solution to show an example for a particular non-static/string date, but rather a variable date, or today's such as CURRENT_DATE(). This WILL use the index on the log_timestamp column.

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

I did the seconds/microseconds to avoid the 12AM case on the next day. However, you could also do `INTERVAL '1 DAY' via comparison operators for a more reader-friendly non-BETWEEN approach:

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

Both of these approaches will use the index and should perform MUCH faster. Both seem to be equally as fast.

asnyder
источник
0

In case you are using SQL parameters to run the query then this would be helpful

SELECT * FROM table WHERE timestamp between concat(date(?), ' ', '00:00:00') and concat(date(?), ' ', '23:59:59')
devesh
источник
0

When I read your question, I thought your were on Oracle DB until I saw the tag 'MySQL'. Anyway, for people working with Oracle here is the way:

SELECT *
FROM table
where timestamp = to_timestamp('21.08.2017 09:31:57', 'dd-mm-yyyy hh24:mi:ss');
KeyMaker00
источник
0

Use

SELECT * FROM table WHERE DATE(2012-05-05 00:00:00) = '2012-05-05' 
Muhammad Fahad
источник