Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL:conteggio per mese (compresi i record mancanti)

Devi generare tutte le date desiderate e poi unire i tuoi dati alle date. Nota anche che è importante inserire alcuni predicati nel ON del join sinistro clausola e altri nel WHERE clausola:

SELECT
  CONCAT(y, '-', LPAD(m, 2, '0')) as byMonth,
  COUNT(`created`) AS Total 
FROM (
  SELECT year(now())     AS y UNION ALL
  SELECT year(now()) - 1 AS y 
) `years`
CROSS JOIN (
  SELECT  1 AS m UNION ALL
  SELECT  2 AS m UNION ALL
  SELECT  3 AS m UNION ALL
  SELECT  4 AS m UNION ALL
  SELECT  5 AS m UNION ALL
  SELECT  6 AS m UNION ALL
  SELECT  7 AS m UNION ALL
  SELECT  8 AS m UNION ALL
  SELECT  9 AS m UNION ALL
  SELECT 10 AS m UNION ALL
  SELECT 11 AS m UNION ALL
  SELECT 12 AS m
) `months`
LEFT JOIN `qualitaet` q
ON YEAR(`created`) = y 
  AND MONTH(`created`) = m
  AND `status` = 1
WHERE STR_TO_DATE(CONCAT(y, '-', m, '-01'), '%Y-%m-%d') 
    >= MAKEDATE(year(now()-interval 1 year),1) + interval 5 month
  AND STR_TO_DATE(CONCAT(y, '-', m, '-01'), '%Y-%m-%d') 
    <= now()
GROUP BY y, m
ORDER BY y, m

Come funziona quanto sopra?

  • CROSS JOIN crea un prodotto cartesiano tra tutti gli anni disponibili e tutti i mesi disponibili. Questo è quello che vuoi, vuoi tutte le combinazioni anno-mese senza interruzioni.
  • LEFT JOIN aggiunge tutti i qualitaet registra il risultato (se esistente) e li unisce al prodotto cartesiano anno-mese di prima. È importante inserire predittivi come status = 1 predicato qui.
  • COUNT(created) conta solo i valori non NULL di created , ovvero quando il LEFT JOIN non produce righe per un dato anno-mese, vogliamo 0 di conseguenza, non 1 , cioè non vogliamo contare il NULL valore.

Una nota sulla performance

Quanto sopra fa un uso massiccio delle operazioni sulle stringhe e dell'aritmetica della data e dell'ora nel tuo ON e WHERE predicati. Questo non funzionerà per molti dati. In tal caso, dovresti pre-troncare e indicizzare meglio i tuoi anni-mesi nel qualitaet tabella e operare solo su quei valori.