Jste na správné cestě, stačí LEFT JOIN
výsledek vašeho dotazu do tabulky názvů měsíců. Potom názvy, které existují ve vašem výsledku, vrátí shodu a NULL
budou vráceny za měsíce, které nejsou ve vašem výsledku. COALESCE
nebo NVL
nebo CASE
konstrukt, cokoli chcete, lze použít k otočení tohoto NULL
do rovného 0
.
Nemusíte vytvářet skutečnou tabulku měsíců, můžete ji získat pomocí inline zobrazení – jednoduše dotazu, který generuje všechna měsíční data.
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
Pokud jde o vrácení všeho za konkrétní rok, podívejte se na podmínku KDE. Předpokládám, že appt_date_time je datum a čas nebo časové razítko. Nechcete psát YEAR(appt_date_time) =2012, protože to zničí šance na použití indexu v tomto sloupci (předpokládám, že se tento sloupec objeví jako první sloupec v indexu). Použitím BETWEEN...AND a porovnáním s doslovným datem a časem můžete mít docela efektivní dotaz, který splňuje požadavek.
Také, pokud GROUP BY
v month(appt_date_time)
mysql zajistí, že výsledky budou seřazeny vzestupně i podle měsíce. Není tedy potřeba samostatného ORDER BY
. Pořadí „noh“ dotazu UNION bude také zachováno pomocí mysql.