Musíte vygenerovat všechna požadovaná data a poté doleva připojit svá data k datům. Všimněte si také, že je důležité umístit některé predikáty do ON
levého spojení klauzule a další v WHERE
klauzule:
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
Jak výše uvedené funguje?
CROSS JOIN
vytvoří karteziánský produkt mezi všemi dostupnými roky a všemi dostupnými měsíci. To je to, co chcete, chcete všechny kombinace rok-měsíc bez mezer.LEFT JOIN
přidá všechnyqualitaet
záznamy k výsledku (pokud existují) a připojí je k kartézskému součinu rok-měsíc z dříve. Je důležité zadat predikáty jakostatus = 1
predikát zde.COUNT(created)
počítá pouze hodnotycreated
, které nejsou NULL , tj. kdyžLEFT JOIN
nevytváří žádné řádky pro žádný daný rok-měsíc, chceme0
v důsledku toho ne1
, tj. nechceme počítatNULL
hodnotu.
Poznámka k výkonu
Výše uvedené silně využívá operace s řetězci a aritmetiku data a času ve vašem ON
a WHERE
predikáty. U velkého množství dat to nebude fungovat. V takovém případě byste měli své rok-měsíce raději předem zkrátit a indexovat v qualitaet
tabulky a pracovat pouze s těmito hodnotami.