Como comparar datas de carimbo de data / hora com parâmetro somente de data no MySQL?


88

Em uma instrução SQL, como posso comparar uma data salva como TIMESTAMP com uma data no formato AAAA-MM-DD?

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

Eu quero que esta consulta retorne todas as linhas com carimbo de data / hora no dia especificado, mas retorna apenas as linhas com carimbo de data / hora da meia-noite.

obrigado

Respostas:


144

Você pode usar a DATE()função para extrair a parte da data do carimbo de data / hora:

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

Porém, se você tiver um índice na coluna de carimbo de data / hora, será mais rápido porque pode utilizar um índice na coluna de carimbo de data / hora, se você tiver um:

SELECT * FROM table
WHERE timestamp BETWEEN '2012-05-05 00:00:00' AND '2012-05-05 23:59:59'

5
Por meio de um pequeno teste que acabei de executar, descobri que usar BETWEEN é mais rápido por um fator de 10X. Apenas para sua informação
DarbyM


6

Como sugerido por alguns, ao usar DATE(timestamp)você está aplicando manipulação à coluna e, portanto, não pode confiar na ordem do índice.

No entanto, o uso BETWEENsó seria confiável se você incluir os milissegundos. No BETWEEN '2012-05-05 00:00:00' AND '2012-05-05 23:59:59'registro de data 2012-05-05 23:59:59.001e hora de exemplo, você exclui registros com um registro de data e hora entre e 2012-05-05 23:59:59.999. Porém, mesmo este método apresenta alguns problemas, devido à precisão dos tipos de dados. Ocasionalmente, 999 milissegundos são arredondados.

A melhor coisa a fazer é:

SELECT * FROM table
WHERE date>='2012-05-05' AND date<'2012-05-06'

5
SELECT * FROM table WHERE timestamp >= '2012-05-05 00:00:00' 
    AND timestamp <= '2012-05-05 23:59:59'

2

Use uma função de conversão de MYSQL:

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

Isso deve funcionar


1

Enquanto eu estava pesquisando, pensei que seria bom modificar a solução BETWEEN para mostrar um exemplo para uma data não estática / string específica, mas sim uma data variável, ou hoje como CURRENT_DATE(). Isso IRÁ usar o índice na coluna 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));

Fiz os segundos / microssegundos para evitar o caso das 12h do dia seguinte. No entanto, você também pode fazer `INTERVAL '1 DAY' por meio de operadores de comparação para uma abordagem não BETWEEN mais amigável à leitura:

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

Ambas as abordagens usarão o índice e devem ter um desempenho MUITO mais rápido. Ambos parecem ser igualmente rápidos.


0

Caso você esteja usando parâmetros SQL para executar a consulta, isso seria útil

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

0

Quando li sua pergunta, pensei que você estava no banco de dados Oracle até que vi a tag 'MySQL'. Enfim, para quem trabalha com a Oracle, aqui está o caminho:

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.