आपको सभी वांछित तिथियां उत्पन्न करने की आवश्यकता है, और फिर अपने डेटा को तिथियों में शामिल करना छोड़ दें। यह भी ध्यान दें कि कुछ विधेय को लेफ्ट जॉइन के ON
. में रखना महत्वपूर्ण है खंड, और अन्य WHERE
. में खंड:
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
उपरोक्त कैसे काम करता है?
CROSS JOIN
एक कार्टेशियन उत्पाद बनाता है सभी उपलब्ध वर्षों और सभी उपलब्ध महीनों के बीच। आप यही चाहते हैं, आप बिना किसी अंतराल के सभी वर्ष-महीने के संयोजन चाहते हैं।LEFT JOIN
सभीqualitaet
जोड़ता है परिणाम के लिए रिकॉर्ड (यदि वे मौजूद हैं) और उन्हें पहले से साल-महीने के कार्टेशियन उत्पाद में शामिल करते हैं।status = 1
. जैसे पूर्वानुमान लगाना महत्वपूर्ण है यहां भविष्यवाणी करें।COUNT(created)
created
. के केवल गैर-शून्य मानों की गणना करता है , यानी जबLEFT JOIN
किसी दिए गए साल-महीने के लिए कोई पंक्ति नहीं बनाता है, हम चाहते हैं0
परिणामस्वरूप,1
. नहीं , यानी हमNULL
. की गणना नहीं करना चाहते हैं मूल्य।
प्रदर्शन पर एक नोट
उपरोक्त आपके ON
. में स्ट्रिंग संचालन और दिनांक समय अंकगणित का भारी उपयोग करता है और WHERE
भविष्यवाणी करता है यह बहुत सारे डेटा के लिए प्रदर्शन नहीं करने वाला है। उस स्थिति में, आपको अपने वर्ष-माहों को qualitaet
में बेहतर ढंग से पूर्व-छंटनी और अनुक्रमणित करना चाहिए तालिका, और केवल उन्हीं मानों पर कार्य करते हैं।