आप सही रास्ते पर हैं, बस LEFT JOIN
आपकी क्वेरी का परिणाम महीने के नाम की तालिका में है। फिर आपके परिणाम में मौजूद नाम एक मैच और एक NULL
. लौटाएंगे उन महीनों के लिए वापस कर दिया जाएगा जो आपके परिणाम में नहीं हैं। एक COALESCE
या NVL
या CASE
निर्माण, जो भी आपको पसंद हो, उस NULL
. को चालू करने के लिए इस्तेमाल किया जा सकता है सीधे 0
. में ।
आपको महीनों की एक वास्तविक तालिका बनाने की आवश्यकता नहीं है, आप इनलाइन दृश्य का उपयोग करके प्राप्त कर सकते हैं - बस एक क्वेरी जो पूरे महीने का डेटा उत्पन्न करती है।
select months.month, coalesce(appts.monthly_total, 0) monthly_total
from (
select 'January' as month
union all select 'February'
union all select 'March'
...etc...
union all select 'December'
) months
left join (
select sum(service_price) as monthly_total,
monthname(appt_date_time) as month
from appt_tbl
inner join services_tbl
on appt_tbl.service_id = services_tbl.service_id
where appt_date_time between '2012-01-01 00:00:00'
and '2012-12-31 23:59:59'
group by month(appt_date_time)
) appts
on months.month = appts.month
जहां तक किसी विशेष वर्ष के लिए प्रत्येक को वापस करने का संबंध है, WHERE की स्थिति देखें। मुझे लगता है कि appt_date_time एक डेटाटाइम या टाइमस्टैम्प है। आप YEAR(appt_date_time) =2012 नहीं लिखना चाहते क्योंकि इससे उस कॉलम पर इंडेक्स का उपयोग करने की संभावना बर्बाद हो जाएगी (मैं मान रहा हूं कि कॉलम इंडेक्स में पहले कॉलम के रूप में दिखाई देता है)। BETWEEN...AND का उपयोग करके और शाब्दिक डेटाटाइम से तुलना करके, आपके पास एक बहुत ही कुशल क्वेरी हो सकती है जो आवश्यकता को पूरा करती है।
साथ ही, यदि आप GROUP BY
month(appt_date_time)
. पर mysql यह सुनिश्चित करेगा कि परिणाम महीने के हिसाब से भी आरोही क्रम में हों। इसलिए अलग से ORDER BY
. की कोई आवश्यकता नहीं है . UNION क्वेरी के 'लेग्स' का क्रम भी mysql द्वारा संरक्षित किया जाएगा।