Anda perlu membuat semua tanggal yang diinginkan, dan kemudian bergabung dengan data Anda ke tanggal. Perhatikan juga bahwa penting untuk meletakkan beberapa predikat di kiri gabungan ON klausa, dan lainnya di WHERE klausa:
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
Bagaimana cara kerja di atas?
CROSS JOINmembuat produk kartesius antara semua tahun yang tersedia dan semua bulan yang tersedia. Inilah yang Anda inginkan, Anda ingin semua kombinasi tahun-bulan tanpa jeda.LEFT JOINmenambahkan semuaqualitaetmencatat hasil (jika ada) dan menggabungkannya ke produk kartesius tahun-bulan dari sebelumnya. Penting untuk menempatkan predikat sepertistatus = 1predikat di sini.COUNT(created)hanya menghitung nilai non-NULL daricreated, yaitu ketikaLEFT JOINtidak menghasilkan baris untuk tahun-bulan tertentu, kami ingin0sebagai hasilnya, bukan1, yaitu kita tidak ingin menghitungNULLnilai.
Catatan tentang performa
Di atas banyak menggunakan operasi string dan aritmatika waktu tanggal di ON . Anda dan WHERE predikat. Ini tidak akan berfungsi untuk banyak data. Dalam hal ini, sebaiknya Anda melakukan pra-pemotongan dan mengindeks tahun-bulan Anda di qualitaet tabel, dan hanya beroperasi pada nilai tersebut.