Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

sql para selecionar um registro para cada mês com uma soma dos registros desses meses


Você está no caminho certo, apenas LEFT JOIN o resultado de sua consulta a uma tabela de nomes de meses. Em seguida, os nomes que existem em seu resultado retornarão uma correspondência e um NULL será devolvido para aqueles meses que não estão no seu resultado. Um COALESCE ou NVL ou CASE construção, o que você quiser, pode ser usado para transformar esse NULL em um 0 direto .

Você não precisa fazer uma tabela real de meses, você pode obter usando uma visualização em linha - simplesmente uma consulta que gera todos os dados do mês.
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 

Quanto ao retorno de tudo para um determinado ano, observe a condição WHERE. Estou assumindo que appt_date_time é um datetime ou timestamp. Você não deseja escrever YEAR(appt_date_time) =2012 porque isso arruinará as chances de usar um índice nessa coluna (suponho que a coluna apareça como a primeira coluna em um índice). Usando um BETWEEN...AND e comparando com datas literais, você pode ter uma consulta bastante eficiente que atende ao requisito.

Além disso, se você GROUP BY em month(appt_date_time) O mysql garantirá que os resultados também sejam classificados em ordem crescente por mês. Portanto, não há necessidade de um ORDER BY separado . A ordem das 'pernas' da consulta UNION também será preservada pelo mysql.