MySQL / SQL: Agrupar por data apenas em uma coluna Datetime

182

Ter uma tabela com uma coluna como: mydate DATETIME...

Eu tenho uma consulta como:

SELECT SUM(foo), mydate FROM a_table GROUP BY a_table.mydate;

Isso agrupará por completo datetime, incluindo horas e minutos. Desejo fazer o grupo até, somente até a data YYYY/MM/DDnão até o YYYY/MM/DD/HH/mm.

Alguém sabe como fazer isto? Ainda posso fazer isso (como sou atm), dinamicamente no meu código, mas estou limpando o código do lixo e isso pode ser feito através do SQL. Não consigo descobrir como :(.

fmsf
fonte
1
Uma abordagem melhor descrita nesta resposta !
Webcoder

Respostas:

287

Transmitir data e hora para uma data e GROUP BY usando esta sintaxe:

SELECT SUM(foo), DATE(mydate) FROM a_table GROUP BY DATE(a_table.mydate);

Ou você pode agrupar pelo alias como @ orlandu63 sugeriu:

SELECT SUM(foo), DATE(mydate) DateOnly FROM a_table GROUP BY DateOnly;

Embora eu não ache que isso faça diferença no desempenho, é um pouco mais claro.

Michael Haren
fonte
1
Tem certeza de que o segundo funciona? No SQL Server, isso falha e falha por um bom motivo. Eu esperaria que falhasse em qualquer outro lugar também. Você pode confirmar que o MySQL realmente lida com essa consulta?
Tomalak
1
Eu apenas tentei e funciona bem. O MySQL é mais permissivo sobre o GROUP BY e confia em você para escrever uma consulta que não seja ambígua.
Bill Karwin
Obrigado pela informação. Não consigo decidir se isso é bom ou não, mas se encaixa perfeitamente na minha opinião sobre o MySQL. De um ponto de vista técnico - como isso deve funcionar? Só posso imaginar que o analisador de consultas substitua o alias na cláusula GROUP BY pela expressão real.
Tomalak
17
É uma armadilha de desempenho! Lembre-se de que o uso dessa função - DATE () não permite alavancar índices nesta coluna.
Kamil Bednarz
Eu usei o primeiro e funcionou como um encanto. Obrigado por esta dica
Helen Neely
20

Descobri que precisava agrupar por mês e ano, para que nenhuma das opções acima funcionasse para mim. Em vez disso, usei date_format

SELECT date
FROM blog 
GROUP BY DATE_FORMAT(date, "%m-%y")
ORDER BY YEAR(date) DESC, MONTH(date) DESC 
Richard Merchant
fonte
2
consulta está com
defeito
19

Ou:

SELECT SUM(foo), DATE(mydate) mydate FROM a_table GROUP BY mydate;

Mais eficiente (eu acho.) Porque você não precisa transmitir minha data duas vezes por linha.

moo
fonte
7
Eu ficaria muito surpreso se o MySQL executasse a conversão duas vezes. Somente funções e expressões agregadas no grupo por lista são permitidas no grupo por instruções de seleção. O mecanismo já precisa saber que as duas expressões são iguais.
Tmdean
1
@Tmdean, 'Somente funções e expressões agregadas no grupo por lista são permitidas no grupo por instruções de seleção' - você pode explicar isso com palavras mais fáceis?
Istiaque Ahmed 11/11
9
SELECT SUM(No), HOUR(dateofissue) 
FROM tablename 
WHERE dateofissue>='2011-07-30' 
GROUP BY HOUR(dateofissue)

Dará a hora pela soma de um dia em particular!

RaK Chowdary
fonte