Anda berada di jalur yang benar, cukup LEFT JOIN hasil kueri Anda ke tabel nama bulan. Kemudian nama yang ada di hasil Anda akan mengembalikan kecocokan, dan NULL akan dikembalikan untuk bulan-bulan yang tidak ada dalam hasil Anda. Sebuah COALESCE atau NVL atau CASE konstruksi, apa pun yang Anda suka, dapat digunakan untuk mengubah NULL menjadi 0 straight lurus .
Anda tidak perlu membuat tabel bulan yang sebenarnya, Anda bisa mendapatkannya dengan menggunakan tampilan sebaris - cukup kueri yang menghasilkan semua data bulan.
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
Adapun untuk mengembalikan semuanya untuk tahun tertentu, lihat kondisi DIMANA. Saya berasumsi appt_date_time adalah datetime atau timestamp. Anda tidak ingin menulis YEAR(appt_date_time) =2012 karena itu akan merusak peluang penggunaan indeks pada kolom itu (saya berasumsi bahwa kolom itu muncul sebagai kolom pertama dalam indeks). Dengan menggunakan BETWEEN...AND dan membandingkan dengan datetime literal, Anda dapat memiliki kueri yang cukup efisien yang memenuhi persyaratan.
Juga, jika Anda GROUP BY pada month(appt_date_time) mysql akan memastikan hasil akan diurutkan berdasarkan bulan juga. Jadi tidak perlu ORDER BY yang terpisah . Urutan 'kaki' kueri UNION juga akan dipertahankan oleh mysql.