sql >> Databasteknik >  >> RDS >> Mysql

MySQL - räkna per månad (inklusive saknade poster)

Du måste generera alla önskade datum och sedan lämna din data till datumen. Observera också att det är viktigt att sätta några predikat i vänster joins ON sats och andra i WHERE klausul:

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

Hur fungerar ovanstående?

  • CROSS JOIN skapar en kartesisk produkt mellan alla tillgängliga år och alla tillgängliga månader. Det här är vad du vill, du vill ha kombinationer hela året och månaden utan luckor.
  • LEFT JOIN lägger till alla qualitaet poster till resultatet (om de finns) och sammanfogar dem med den kartesiska årsprodukten från tidigare. Det är viktigt att sätta prediakter som status = 1 predikat här.
  • COUNT(created) räknar endast icke-NULL-värden för created , dvs när LEFT JOIN producerar inga rader för en given år-månad, vi vill ha 0 som ett resultat, inte 1 , det vill säga vi vill inte räkna NULL värde.

En notering om prestanda

Ovanstående använder mycket strängoperationer och aritmetik för datum och tid i din ON och WHERE predikat. Detta kommer inte att fungera för mycket data. I så fall bör du bättre förkorta och indexera dina årsmånader i qualitaet tabell och arbeta endast på dessa värden.




  1. 2019 PostgreSQL-trendrapport:Privat vs. Public Cloud, Migrations, Database Combinations &Top Reasones Used

  2. Distribuera MySQL relationsdatabaser på Ubuntu 12.04 (Precis Pangolin)

  3. Migrera en Oracle-databas till MySQL på AWS, del 2

  4. Hur genererar jag en unik, slumpmässig sträng för en av mina MySql-tabellkolumner?