109 votes

Comment grouper par semaine dans MySQL?

Oracle tableau server offre une fonction intégrée, TRUNC(timestamp,'DY'). Cette fonction permet de convertir un timestamp à minuit, le dimanche précédent. Quelle est la meilleure façon de le faire dans MySQL?

Oracle propose également TRUNC(timestamp,'MM') pour convertir un timestamp à minuit le premier jour du mois au cours duquel il se produit. Dans MySQL, c'est simple:

TIMESTAMP(DATE_FORMAT(timestamp, '%Y-%m-01'))

Mais cette DATE_FORMAT astuce ne fonctionne pas pendant des semaines. Je suis conscient de l' WEEK(timestamp) de la fonction, mais je ne veux vraiment pas le numéro de semaine dans l'année; ce genre de choses est, pour la programmation pluriannuelle des travaux.

141voto

mjv Points 38081

Vous pouvez utiliser les deux ANS(timestamp) et de la SEMAINE(timestamp), et utiliser les deux de ces expressions dans la sélection et la clause GROUP BY.

Pas trop élégant, mais fonctionnel...

Et bien sûr, vous pouvez combiner ces deux pièces en une seule expression, c'est à dire quelque chose comme

SELECT CONCAT(YEAR(timestamp), '/', WEEK(timestamp)), etc...
FROM ...
WHERE ..
GROUP BY CONCAT(YEAR(timestamp), '/', WEEK(timestamp))

Edit: Comme Martin xx points, vous pouvez aussi utiliser le YEARWEEK() de la fonction, même si sa production n'est pas que les yeux convivial que le plus de la formule ci-dessus.

Edit 2 [3 1/2 ans plus tard!]:
YEARWEEK() avec le second argument optionnel (mode) soit 0 ou 2 est probablement la meilleure façon de regrouper les données complète semaines (c'est à dire y compris pour les semaines qui chevauchent sur le 1er janvier), si c'est ce qui est souhaité. L'ANNÉE() / SEMAINE() approche initialement proposé dans cette réponse a pour effet de fractionner les données agrégées pour ces "chevauchant" semaines en deux: l'un avec l'année précédente, l'un avec la nouvelle année.
Un clean-cut, chaque année, au prix d'avoir jusqu'à deux semaines partielles, un à chaque extrémité, est souvent souhaitée dans la comptabilité, etc. et pour que l'ANNÉE() / SEMAINE() approche est la meilleure.

52voto

Ollie Jones Points 20488

Je l'ai compris ... c'est un peu lourd, mais le voici.

FROM_DAYS (TO_DAYS (TIMESTAMP) -MOD (TO_DAYS (TIMESTAMP) -1, 7))


modifier

Des années ont passé et je me suis enfin mis à écrire ça. http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/

41voto

B Seven Points 6496

La réponse acceptée ci-dessus n'a pas fonctionné pour moi, car elle a ordonné les semaines par ordre alphabétique et non par ordre chronologique:

 2012/1
2012/10
2012/11
...
2012/19
2012/2
 

Voici ma solution pour compter et groupe par semaine:

 SELECT CONCAT(YEAR(date), '/', WEEK(date)) AS week_name, 
       YEAR(date), WEEK(date), COUNT(*)
FROM column_name
GROUP BY week_name
ORDER BY YEAR(DATE) ASC, WEEK(date) ASC
 

Génère:

 YEAR/WEEK   YEAR   WEEK   COUNT
2011/51     2011    51      15
2011/52     2011    52      14
2012/1      2012    1       20
2012/2      2012    2       14
2012/3      2012    3       19
2012/4      2012    4       19
 

26voto

martin clayton Points 41306

Vous pouvez obtenir la concaténation de l'année et le numéro de la semaine (200945) à l'aide de la YEARWEEK() fonction. Si je comprends votre objectif correctement, cela devrait vous permettre de regrouper vos données pluriannuelle.

Si vous avez besoin de le timestamp réelle pour le début de la semaine, c'est moins sympa:

DATE_SUB( field, INTERVAL DAYOFWEEK( field ) - 1 DAY )

Pour le mois de votre commande, vous pouvez envisager de la LAST_DAY() la fonction de tri serait le dernier jour du mois, mais qui devrait être l'équivalent de tri sur le premier jour du mois ... n'est-ce pas?

4voto

Xavier Points 19

Il suffit d’ajouter ceci dans la sélection:

 DATE_FORMAT($yourDate, \'%X %V\') as week
 

Et

 group_by(week);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X