MySQL / SQL: Grouper par date uniquement sur une colonne Datetime

182

Avoir une table avec une colonne comme: mydate DATETIME...

J'ai une question telle que:

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

Cela regroupera par le plein datetime, y compris les heures et les minutes. Je souhaite faire le groupe d'ici, uniquement à la date et YYYY/MM/DDnon au YYYY/MM/DD/HH/mm.

Quelqu'un sait-il comment faire ça? Je peux toujours le faire (comme je suis atm), dynamiquement dans mon code, mais je nettoie le code de la corbeille et cela peut être fait via le SQL, je ne peux tout simplement pas savoir comment :(.

fmsf
la source
1
Une meilleure approche décrite dans cette réponse !
webcoder

Réponses:

288

Convertissez le datetime en une date, puis GROUP BY en utilisant cette syntaxe:

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

Ou vous pouvez GROUP BY l'alias comme @ orlandu63 suggéré:

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

Même si je ne pense pas que cela changera les performances, c'est un peu plus clair.

Michael Haren
la source
1
Etes-vous sûr que le second fonctionne? Sur SQL Server, cela échoue et il échoue pour une bonne raison. Je m'attendrais à ce qu'il échoue également ailleurs. Pouvez-vous confirmer que MySQL gère réellement cette requête?
Tomalak
1
Je viens de l'essayer et cela fonctionne bien. MySQL est plus permissif sur GROUP BY et il vous fait confiance pour écrire une requête qui n'est pas ambiguë.
Bill Karwin
Merci pour l'info. Je ne peux pas décider si c'est une bonne chose ou non, mais cela correspond parfaitement à mon opinion sur MySQL. À partir d'un point de vue technique - comment cela est-il censé fonctionner? Je peux seulement imaginer que l'analyseur de requête remplace l'alias dans la clause GROUP BY par l'expression réelle.
Tomalak
17
C'est un piège de performance! Gardez à l'esprit que l'utilisation d'une telle fonction - DATE () ne vous permet pas d'exploiter les index de cette colonne.
Kamil Bednarz
J'ai utilisé le premier et cela a fonctionné comme un charme. Merci pour cette astuce
Helen Neely
20

J'ai trouvé que j'avais besoin de regrouper par mois et par année, donc aucun des éléments ci-dessus ne fonctionnait pour moi. Au lieu de cela, j'ai utilisé date_format

SELECT date
FROM blog 
GROUP BY DATE_FORMAT(date, "%m-%y")
ORDER BY YEAR(date) DESC, MONTH(date) DESC 
Richard Merchant
la source
2
la requête est
irrecevable
19

Ou:

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

Plus efficace (je pense.) Parce que vous n'avez pas à lancer ma date deux fois par ligne.

meuglement
la source
7
Je serais très surpris si MySQL exécutait la conversion deux fois. Seules les fonctions d'agrégation et les expressions de la liste group by sont autorisées dans les instructions group by select. Le moteur doit déjà savoir que les deux expressions sont identiques.
Tmdean
1
@Tmdean, «Seules les fonctions d'agrégation et les expressions du groupe par liste sont autorisées dans les instructions de groupe par sélection» - pouvez-vous l'expliquer en termes plus simples?
Istiaque Ahmed
9
SELECT SUM(No), HOUR(dateofissue) 
FROM tablename 
WHERE dateofissue>='2011-07-30' 
GROUP BY HOUR(dateofissue)

Il donnera l'heure par somme d'un jour particulier!

RaK Chowdary
la source