sql >> Database >  >> RDS >> Mysql

MySQL - tel per maand (inclusief ontbrekende records)

U moet alle gewenste datums genereren en vervolgens uw gegevens bij de datums voegen. Merk ook op dat het belangrijk is om enkele predikaten in de ON . van de linker join te plaatsen clausule, en andere in de WHERE clausule:

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

Hoe werkt het bovenstaande?

  • CROSS JOIN maakt een cartesiaans product tussen alle beschikbare jaren en alle beschikbare maanden. Dit is wat je wilt, je wilt alle jaar-maand combinaties zonder hiaten.
  • LEFT JOIN voegt alle qualitaet . toe records bij het resultaat (indien aanwezig) en voegt ze samen met het jaar-maand cartesiaanse product van voorheen. Het is belangrijk om prediacten te plaatsen zoals de status = 1 predikaat hier.
  • COUNT(created) telt alleen niet-NULL-waarden van created , d.w.z. wanneer de LEFT JOIN produceert geen rijen voor een bepaalde jaar-maand, we willen 0 als resultaat, niet 1 , d.w.z. we willen de NULL . niet tellen waarde.

Een opmerking over prestaties

Het bovenstaande maakt veel gebruik van tekenreeksbewerkingen en datum-tijdberekeningen in uw ON en WHERE predikaten. Dit gaat niet werken voor veel gegevens. In dat geval kunt u uw jaarmaanden beter vooraf inkorten en indexeren in de qualitaet tabel, en werk alleen op die waarden.




  1. Selecteer een groep rijen die overeenkomen met alle items in een lijst

  2. Hoe de primaire sleutel voor automatisch verhogen in PostgreSQL in te stellen?

  3. wat betekent niet-geverifieerde gebruiker in MYSQL?

  4. Hoe kan ik de laatste twee woorden in een zin in PostgreSQL matchen?