web-dev-qa-db-fra.com

Requête MySQL GROUP par jour / mois / année

Est-il possible que je fasse une requête simple pour compter combien d'enregistrements que j'ai dans une période de temps déterminée, comme une année, un mois ou un jour, ayant un champ TIMESTAMP, comme:

SELECT COUNT(id)
FROM stats
WHERE record_date.YEAR = 2009
GROUP BY record_date.YEAR

Ou même:

SELECT COUNT(id)
FROM stats
GROUP BY record_date.YEAR, record_date.MONTH

Avoir une statistique mensuelle.

Merci!

592
Fernando Barrocal
GROUP BY YEAR(record_date), MONTH(record_date)

Découvrez le fonctions de date et heure dans MySQL.

932
codelogic
GROUP BY DATE_FORMAT(record_date, '%Y%m')

Note (principalement aux votants descendants potentiels). Actuellement, cela n’est peut-être pas aussi efficace que d’autres suggestions. Néanmoins, je le laisse comme alternative, et aussi, qui peut servir à voir à quelle vitesse les autres solutions sont rapides. (Car vous ne pouvez pas vraiment dire rapidement de lent jusqu'à ce que vous voyiez la différence.) De plus, avec le temps, des modifications pourraient être apportées au moteur de MySQL en ce qui concerne l'optimisation afin de rendre cette solution, à certains (peut-être pas si lointain) pour devenir tout à fait comparable en efficacité avec la plupart des autres.

213
Andriy M

J'ai essayé d'utiliser la déclaration 'WHERE' ci-dessus, je pensais que c'était correct puisque personne ne l'a corrigée, mais j'avais tort. Après quelques recherches, j'ai découvert qu'il s'agissait de la bonne formule pour l'instruction WHERE. Le code devient ainsi:

SELECT COUNT(id)  
FROM stats  
WHERE YEAR(record_date) = 2009  
GROUP BY MONTH(record_date)
40
dimazaid

essaye celui-là

SELECT COUNT(id)
FROM stats
GROUP BY EXTRACT(YEAR_MONTH FROM record_date)

EXTRACT (unit FROM date) La fonction est préférable car moins de regroupement est utilisé et la fonction renvoie une valeur numérique.

La condition de comparaison lors du regroupement sera plus rapide que la fonction DATE_FORMAT (qui renvoie une valeur de chaîne). Essayez d’utiliser la fonction | champ qui renvoie une valeur non chaîne pour la condition de comparaison SQL (WHERE, HAVING, ORDER BY, GROUP BY).

39
fu-chi

Si votre recherche s'étend sur plusieurs années et que vous souhaitez toujours regrouper tous les mois, je suggère:

version n ° 1:

SELECT SQL_NO_CACHE YEAR(record_date), MONTH(record_date), COUNT(*)
FROM stats
GROUP BY DATE_FORMAT(record_date, '%Y%m')

version n ° 2 (plus efficace) :

SELECT SQL_NO_CACHE YEAR(record_date), MONTH(record_date), COUNT(*)
FROM stats
GROUP BY YEAR(record_date)*100 + MONTH(record_date)

J'ai comparé ces versions sur une grande table avec 1 357 918 lignes ( innodb ), et la deuxième version semble avoir de meilleurs résultats.

version1 (moyenne de 10 exécutions) : 1,404 seconde
version2 (moyenne de 10 exécutions) : 0,780 seconde

(La clé SQL_NO_CACHE a été ajoutée pour empêcher MySQL de CACHING aux requêtes.)

25
mr.baby123

Si vous souhaitez grouper par date dans MySQL, utilisez le code ci-dessous:

 SELECT COUNT(id)
 FROM stats
 GROUP BY DAYOFMONTH(record_date)

J'espère que cela fera gagner un peu de temps à ceux qui vont trouver ce fil.

16
Haijerome

Si vous souhaitez filtrer les enregistrements pour une année particulière (par exemple 2000), optimisez la clause WHERE de la manière suivante:

SELECT MONTH(date_column), COUNT(*)
FROM date_table
WHERE date_column >= '2000-01-01' AND date_column < '2001-01-01'
GROUP BY MONTH(date_column)
-- average 0.016 sec.

Au lieu de:

WHERE YEAR(date_column) = 2000
-- average 0.132 sec.

Les résultats ont été générés sur une table contenant 300 000 lignes et un index sur la colonne de date.

En ce qui concerne la clause GROUP BY, j'ai testé les trois variantes par rapport au tableau mentionné ci-dessus; Voici les résultats:

SELECT YEAR(date_column), MONTH(date_column), COUNT(*)
FROM date_table
GROUP BY YEAR(date_column), MONTH(date_column)
-- codelogic
-- average 0.250 sec.

SELECT YEAR(date_column), MONTH(date_column), COUNT(*)
FROM date_table
GROUP BY DATE_FORMAT(date_column, '%Y%m')
-- Andriy M
-- average 0.468 sec.

SELECT YEAR(date_column), MONTH(date_column), COUNT(*)
FROM date_table
GROUP BY EXTRACT(YEAR_MONTH FROM date_column)
-- fu-chi
-- average 0.203 sec.

Le dernier est le gagnant.

12
Salman A

Solution complète et simple offrant une alternative similaire, plus performante mais plus courte et plus flexible, actuellement active:

SELECT COUNT(*) FROM stats
-- GROUP BY YEAR(record_date), MONTH(record_date), DAYOFMONTH(record_date)
GROUP BY DATE_FORMAT(record_date, '%Y-%m-%d')
10
Cees Timmerman

Si vous souhaitez obtenir des statistiques mensuelles avec le nombre de lignes par mois de chaque année commandée par le dernier mois, essayez ceci:

SELECT count(id),
      YEAR(record_date),
      MONTH(record_date) 
FROM `table` 
GROUP BY YEAR(record_date),
        MONTH(record_date) 
ORDER BY YEAR(record_date) DESC,
        MONTH(record_date) DESC
7
user3019799

Vous pouvez faire ceci simplement Mysql DATE_FORMAT () fonction dans GROUP BY. Vous voudrez peut-être ajouter une colonne supplémentaire pour plus de clarté dans certains cas, par exemple lorsque les enregistrements couvrent plusieurs années, puis que le même mois se produit plusieurs années. Ici, vous pouvez personnaliser cette option. Veuillez lire ceci avant de commencer. J'espère que cela vous sera très utile. Voici un exemple de requête pour votre compréhension

SELECT
    COUNT(id),
    DATE_FORMAT(record_date, '%Y-%m-%d') AS DAY,
    DATE_FORMAT(record_date, '%Y-%m') AS MONTH,
    DATE_FORMAT(record_date, '%Y') AS YEAR,

FROM
    stats
WHERE
    YEAR = 2009
GROUP BY
    DATE_FORMAT(record_date, '%Y-%m-%d ');
6
Faisal

La requête suivante a fonctionné pour moi dans Oracle Database 12c Release 12.1.0.1.0

SELECT COUNT(*)
FROM stats
GROUP BY 
extract(MONTH FROM TIMESTAMP),
extract(MONTH FROM TIMESTAMP),
extract(YEAR  FROM TIMESTAMP);
4
Minisha

Je préfère optimiser la sélection du groupe sur un an comme suit:

SELECT COUNT(*)
  FROM stats
 WHERE record_date >= :year 
   AND record_date <  :year + INTERVAL 1 YEAR;

De cette façon, vous pouvez simplement lier l’année en une fois, par exemple. '2009', avec un paramètre nommé et vous n'avez pas à vous soucier d'ajouter '-01-01' ou de passer '2010' séparément.

De plus, étant donné que nous ne faisons que compter les lignes et que id n'est jamais NULL, je préfère COUNT(*) à COUNT(id).

2
Arth

.... group by to_char(date, 'YYYY') -> 1989

.... group by to_char(date,'MM') -> 05

.... group by to_char(date,'DD') ---> 23

.... group by to_char(date,'MON') ---> PEUT

.... group by to_char(date,'YY') ---> 89

0
aromita sen