Sie müssen alle gewünschten Daten generieren und dann Ihre Daten mit den Daten verknüpfen. Beachten Sie auch, dass es wichtig ist, einige Prädikate in ON
des linken Joins zu setzen -Klausel und andere in WHERE
Klausel:
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
Wie funktioniert das obige?
CROSS JOIN
erstellt ein kartesisches Produkt zwischen allen verfügbaren Jahren und allen verfügbaren Monaten. Das ist, was Sie wollen, Sie wollen alle Jahr-Monats-Kombinationen ohne Lücken.LEFT JOIN
fügt allequalitaet
hinzu Datensätze zum Ergebnis (falls vorhanden) und verbindet sie mit dem kartesischen Jahr-Monat-Produkt von vorher. Es ist wichtig Prädikate wie denstatus = 1
zu setzen Prädikat hier.COUNT(created)
zählt nur Nicht-NULL-Werte voncreated
, d.h. wenn derLEFT JOIN
keine Zeilen für einen gegebenen Jahr-Monat erzeugt, wir wollen0
folglich nicht1
, d.h. wir wollenNULL
nicht zählen Wert.
Ein Hinweis zur Leistung
Das Obige macht in Ihrem ON
starken Gebrauch von String-Operationen und Datums-Zeit-Arithmetik und WHERE
Prädikate. Dies wird für viele Daten nicht funktionieren. In diesem Fall sollten Sie Ihre Jahr-Monate besser in der qualitaet
vorkürzen und indizieren Tabelle und arbeiten nur mit diesen Werten.