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.