sql >> Base de Datos >  >> RDS >> Mysql

sql para seleccionar un registro para cada mes con una suma de registros de ese mes

Estás en el camino correcto, solo LEFT JOIN el resultado de su consulta a una tabla de nombres de meses. Luego, los nombres que existen en su resultado devolverán una coincidencia y un NULL será devuelto por aquellos meses que no están en su resultado. UN COALESCE o NVL o CASE La construcción, lo que quieras, se puede usar para convertir eso NULL en un 0 recto .

No necesita hacer una tabla real de meses, puede obtenerla usando una vista en línea, simplemente una consulta que genera todos los datos del mes.

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 

En cuanto a devolver todo para un año en particular, mire la condición DONDE. Supongo que appt_date_time es una fecha y hora o una marca de tiempo. No desea escribir AÑO (appt_date_time) =2012 porque eso arruinará las posibilidades de usar un índice en esa columna (supongo que esa columna aparece como la primera columna en un índice). Al usar BETWEEN... AND y comparar con fechas y horas literales, puede tener una consulta bastante eficiente que cumpla con el requisito.

Además, si GROUP BY el month(appt_date_time) mysql se asegurará de que los resultados también se ordenen de forma ascendente por mes. Así que no hay necesidad de un ORDER BY separado . mysql también conservará el orden de los 'tramos' de la consulta UNION.