Como selecionar a data da coluna datetime?


238

Eu tenho uma coluna do tipo "datetime" com valores como 2009-10-20 10:00:00

Gostaria de extrair a data do datetime e escrever uma consulta como:

SELECT * FROM 
data 
WHERE datetime = '2009-10-20' 
ORDER BY datetime DESC

A seguinte é a melhor maneira de fazer isso?

SELECT * FROM 
data 
WHERE datetime BETWEEN('2009-10-20 00:00:00' AND '2009-10-20 23:59:59')
ORDER BY datetime DESC

No entanto, isso retorna um conjunto de resultados vazio. Alguma sugestão?

Respostas:


456

Você pode usar a DATE()função do MySQL :

WHERE DATE(datetime) = '2009-10-20'

Você também pode tentar o seguinte:

WHERE datetime LIKE '2009-10-20%'

Veja esta resposta para obter informações sobre as implicações de desempenho do uso LIKE.


2
tentei este: Where DATE (datetime) =
'20

44
O primeiro é muito lento e ignora os índices. É melhor ter LIKE 'data%'
Kachar

ONDE DATE (data e hora) LIKE '% keyword%' o seu trabalho, graças
silvia zulinka

2
Eu acredito que isso não funcionará conforme o esperado se o fuso horário do Rails for algo diferente do UTC. Isso ocorre porque DATE () resolve o valor da coluna para UTC. Portanto, uma data como "Sex, 30 de dezembro de 2016 00:00:00 SGT +08: 00", que esperamos encontrar, se consultamos "30-12-2016" não será encontrada. Por quê? Porque DATE () resolverá seu equivalente ao UTC antes de fazer a comparação, que é "29-12-2016 16:00:00 UTC". Corrija-me se eu estiver errado, pois isso também foi um problema para você até recentemente.
Tikiboy 4/17/17

WHERE DATE (datetime) = '{? Sdate} funciona perfeitamente para um parâmetro do Crystal Reports! Bom trabalho!
precisa saber é o seguinte

94

O uso WHERE DATE(datetime) = '2009-10-20' tem problemas de desempenho . Como indicado aqui :

  • ele calculará DATE()para todas as linhas, incluindo aquelas que não correspondem.
  • tornará impossível usar um índice para a consulta.

Use BETWEENou >, <, =operadores, que permitem a utilização de um índice de:

SELECT * FROM data 
WHERE datetime BETWEEN '2009-10-20 00:00:00' AND '2009-10-20 23:59:59'

Atualização: o impacto no uso em LIKEvez de operadores em uma coluna indexada é alto . Estes são alguns resultados de teste em uma tabela com 1.176.000 linhas:

  • usando datetime LIKE '2009-10-20%'=> 2931ms
  • usando datetime >= '2009-10-20 00:00:00' AND datetime <= '2009-10-20 23:59:59'=> 168ms

Ao fazer uma segunda chamada na mesma consulta, a diferença é ainda maior: 2984ms vs 7ms (sim, apenas 7 milissegundos!). Encontrei isso ao reescrever algum código antigo em um projeto usando o Hibernate.


Interessante, se a implementação do MySql se converter automaticamente DATE(datetime)para BETWEEN AND acompanhar as cenas, obteremos uma breve declaração e um desempenho interessante. Por que não? Por que eles não fizeram isso? :)
Cereja

Porque algo como DATE(datetime) in (:list)não funciona comBETWEEN
Tim

25

Você pode formatar o datetime para a parte YMD:

DATE_FORMAT(datetime, '%Y-%m-%d')

2
E desta forma você pode obter apenas a parte do tempo, se necessário:DATE_FORMAT(datetime, '%H:%i:%S')
Metafaniel

isso funciona muito bem na formatação da data e hora, mas, em troca, o banco de dados retornará uma nova matriz para definir o nome e apenas o nome desejado no final DATE_FORMAT (columnName, '% Y-% m-% d') arrayName para obter mais detalhes, verifique documentação dev.mysql.com/doc/refman/8.0/en/…
Ridha Rezzag 18/01/19

15

Embora todas as respostas na página retornem o resultado desejado, todas elas apresentam problemas de desempenho. Nunca execute cálculos nos campos da WHEREcláusula (incluindo um DATE()cálculo), pois esse cálculo deve ser executado em todas as linhas da tabela.

A BETWEEN ... ANDconstrução é inclusiva para ambas as condições de borda, exigindo que se especifique a sintaxe 23:59:59 na data final, a qual possui outros problemas (transações de microssegundos, que acredito que o MySQL não deu suporte em 2009 quando a pergunta foi feita).

A maneira correta de consultar um timestampcampo MySQL para um dia específico é verificar Maior que Igual à data desejada e Menor que para o dia seguinte, sem hora especificada.

WHERE datetime>='2009-10-20' AND datetime<'2009-10-21'

Este é o método de mais rápido desempenho, com menos memória e menos recursos, além de suportar todos os recursos e casos de canto do MySQL, como precisão de carimbo de data / hora de sub-segundo. Além disso, é uma prova futura.


1
E, usando seu argumento de desempenho, os "> =" e "<" são calculados igualmente em cada linha da tabela, ou o servidor SQL apenas "magicamente" sabe se um número é maior que outro? :-)
Javier Guerrero

@JavierGuerrero: Meu exemplo compara duas constantes: uma da tabela e uma string literal.
dotancohen

O "da tabela" não é uma constante, varia para cada linha, portanto, o mesmo cálculo deve ser feito para cada linha (e também, ambos devem ser convertidos em época para realizar a comparação)
Javier Guerrero

9

Aqui estão todos os formatos

Digamos que esta seja a coluna que contém o datetimevalor, tabela data.

+--------------------+
| date_created       |
+--------------------+
| 2018-06-02 15:50:30|
+--------------------+

mysql> select DATE(date_created) from data;
+--------------------+
| DATE(date_created) |
+--------------------+
| 2018-06-02         |
+--------------------+

mysql> select YEAR(date_created) from data;
+--------------------+
| YEAR(date_created) |
+--------------------+
|               2018 |
+--------------------+

mysql> select MONTH(date_created) from data;
+---------------------+
| MONTH(date_created) |
+---------------------+
|                   6 |
+---------------------+

mysql> select DAY(date_created) from data;
+-------------------+
| DAY(date_created) |
+-------------------+
|                 2 |
+-------------------+

mysql> select HOUR(date_created) from data;
+--------------------+
| HOUR(date_created) |
+--------------------+
|                 15 |
+--------------------+

mysql> select MINUTE(date_created) from data;
+----------------------+
| MINUTE(date_created) |
+----------------------+
|                   50 |
+----------------------+

mysql> select SECOND(date_created) from data;
+----------------------+
| SECOND(date_created) |
+----------------------+
|                   31 |
+----------------------+

5

Você pode usar:

DATEDIFF ( day , startdate , enddate ) = 0

Ou:

DATEPART( day, startdate ) = DATEPART(day, enddate)
AND 
DATEPART( month, startdate ) = DATEPART(month, enddate)
AND
DATEPART( year, startdate ) = DATEPART(year, enddate)

Ou:

CONVERT(DATETIME,CONVERT(VARCHAR(12), startdate, 105)) = CONVERT(DATETIME,CONVERT(VARCHAR(12), enddate, 105))

5

maneira simples e melhor de usar a função de data

exemplo

SELECT * FROM 
data 
WHERE date(datetime) = '2009-10-20' 

OU

SELECT * FROM 
data 
WHERE date(datetime ) >=   '2009-10-20'  && date(datetime )  <= '2009-10-20'

-5

Bem, usar LIKEna declaração é a melhor opção WHERE datetime LIKE '2009-10-20%' que deve funcionar nesse caso

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.