あなたは正しい方向に進んでいます。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によって保持されます。