MySQL compara string DATE com string do campo DATETIME

89

Tenho uma pergunta: é possível selecionar em um banco de dados MySQL comparando uma string DATE "2010-04-29" com as strings armazenadas como DATETIME (2010-04-29 10:00)?

Eu tenho um selecionador de data que filtra os dados e gostaria de consultar a tabela pelo campo DATETIME assim:

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

... e eu gostaria de obter a linha que tem o valor DATETIME de "2010-04-29 10:00".

Alguma sugestão? Obrigado.

Manny Calavera
fonte

Respostas:

159

Use o seguinte:

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

Apenas para referência, tenho uma tabela de 2 milhões de registros, fiz uma consulta semelhante. A resposta de Salils demorou 4,48 segundos, a anterior demorou 2,25 segundos.

Portanto, se a mesa for GRANDE, eu sugeriria isso.

David
fonte
8
A primeira resposta é muito lenta, porque deve formatar cada data e hora em uma string antes da comparação. Seu é melhor, porque compara diretamente apenas a parte da data do campo, mas ainda não pode usar o índice (testado no mysql 5.1)
Marki555
1
Se o desempenho for um problema, pode valer a pena considerar armazenar a parte da data e da hora separadamente, para que um INDEX possa ser colocado na parte da data.
Thijs Riezebeek
1
Esta consulta não poderá usar o índice se startTimeestiver indexada.
Zamrony P. Juhara
41

Se você deseja selecionar todas as linhas em que a parte DATE de uma coluna DATETIME corresponde a um determinado literal, você não pode fazer desta forma:

WHERE startTime = '2010-04-29'

porque o MySQL não pode comparar DATE e DATETIME diretamente. O que o MySQL faz, ele estende o literal DATE fornecido com a hora '00: 00: 00 '. Então sua condição se torna

WHERE startTime = '2010-04-29 00:00:00'

Certamente não é o que você quer!

A condição é um intervalo e, portanto, deve ser fornecida como intervalo. Existem várias possibilidades:

WHERE startTime BETWEEN '2010-04-29 00:00:00' AND '2010-04-29 23:59:59'
WHERE startTime >= '2010-04-29' AND startTime < ('2010-04-29' + INTERVAL 1 DAY)

Há uma pequena possibilidade de o primeiro estar errado - quando sua coluna DATETIME usa resolução de subsegundos e há um compromisso às 23:59:59 + epsilon. Em geral, sugiro usar a segunda variante.

Ambas as variantes podem usar um índice no startTime que se tornará importante quando a tabela crescer.

XL_
fonte
9
A versão de David não é boa, não pode usar índices. Para usar um índice, tem de filtro sobre a coluna directamente, não em resultado de uma função ( date(), year(), datediff()ou qualquer semelhante)
Marki555
Eu estava procurando como o mysql converte a data em datetime, obrigado por limpar isso adiciona 00:00:00. agora meus resultados fazem sentido
Contador م
1
Esta é a solução rápida correta em comparação com outras respostas que não podem usar o índice, se disponível
Zamrony P. Juhara
23
SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"

OU

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'
Salil
fonte
23
Esta é uma pergunta terrível. Evite isso a todo custo. Se houver um índice em startTime, ele não pode ser usado por esta consulta, pois está aplicando uma função à coluna em vez de usá-la diretamente. Isso significa que qualquer consulta como essa exigirá uma verificação completa da tabela. Em uma mesa grande, isso significa uma consulta extremamente lenta.
steveayre
Eu concordo, a resposta dele está errada - a resposta correta foi postada por David abaixo.
mindplay.dk
1
Por favor, use a resposta do David, porque é muito mais rápido. Este é válido, mas não é bom para a velocidade ...
xarlymg89
1
@CarlosAlbertoMartínezGadea Esta versão é lenta porque tem que formatar cada valor em string antes da comparação ... A versão de David não precisa, mas ainda não pode usar índices, então não é a ideal. Veja a resposta de XL_ para uma versão que pode usar o índice. Infelizmente, não há maneira melhor de fazer isso corretamente no mysql
Marki555 de
1
Eu votei contra esta resposta porque a consulta não pode usar um índice, enquanto a resposta de @ XL_ usa.
pedromanoel
2
SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')

isso para o formato de data e hora no mysql usando DATE_FORMAT(date,format).

RT
fonte
1
SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29';

ajuda, você pode converter os valores como DATEantes de comparar.

Sarath
fonte
0

Você pode transmitir o campo DATETIME para DATE como:

SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'

Isso é muito eficiente.

SGAmpere
fonte
1
Não, também não é eficiente. não será possível usar o índice se startTimeestiver indexado
Zamrony P. Juhara
-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

Você também pode usar operadores de comparação nas datas do MySQL se quiser encontrar algo antes ou depois. Isso ocorre porque eles são escritos de tal forma (do maior ao menor valor com zeros à esquerda) que uma simples classificação de string os classificará corretamente.

Fletcher Moore
fonte