2011-05-24 25 views
5

cuál es una buena manera de unirse a 1-12 en una columna a un montón de cuentas por mes? ... en SQLconsulta SQL para calcular los recuentos por mes

SELECT 
    months???, 
    count(whatever1) count1, 
    count(whatever2) count2 
FROM 
    months???? 
    LEFT JOIN whatever1 ON 
     month(whatever1.Date) = months???.monthid 
    LEFT JOIN whatever2 ON 
     month(whatever2.Date) = months???.monthid 
GROUP BY 
    months??? 

algo que podría terminar como

"month","whatever1count","whatever2count" 
1,null,5 
2,null,3 
3,null,null 
4,2,3 
5,36,73 
6,2,null 
7,45,944 
8,null,12 
9,1467,3 
10,null,2 
11,3,25 
12,4,null 

Editar- básicamente donde es una forma pulida para obtener mis lista meses/mesa/lo que sea

+1

¿Qué base de datos está utilizando - MSSQL, Oracle, MySQL? Todos difieren en formas sutiles. –

+0

@ Steviepoo- MSSQL – spaghetticowboy

Respuesta

4

muchas maneras ... uno que funcionaba bien para mí en muchas aplicaciones en un trabajo anterior era construir una tabla de marcos de tiempo

id - Year - Month - StartStamp   - End Stamp 
1 - 2008 - January - 1/1/2008 00:00:00.000 - 1/31/2008 23:59:59.999 

continuación, sólo puede unirse contra la mesa, donde los plazos de su campo de fecha está entre startstamp y endstamp.

Esto hace que sea fácil de tirar de un cierto período de tiempo, o todos los períodos de tiempo ...

suyo podría ser más sencillo, con sólo 12 registros (es decir, 1 - enero) y uniéndose en DATEPART (m, DateColumn)

select mon.monthNumber, mon.monthName, 
     count(a.*) as count1, count(b.*) as count2 
from months mon 
left join whatever1 a on DATEPART(m,a.Date) = mon.monthNumber 
left join whatever2 b on DATEPART(m,b.Date) = mon.monthNumber 
group by mon.monthNumber, mon.monthName 

también podría hacer lo meses ad hoc, así:

select mon.monthNumber, mon.monthName, 
     count(a.*) as count1, count(b.*) as count2 
from (
    select 1 as monthNumber, 'January' as monthName 
    union 
    select 2 as monthNumber, 'February' as monthName 
    union 
    select 3 as monthNumber, 'March' as monthName 
    union 
    ......etc..... 
) mon 
left join whatever1 a on DATEPART(m,a.Date) = mon.monthNumber 
left join whatever2 b on DATEPART(m,b.Date) = mon.monthNumber 
group by mon.monthNumber, mon.monthName 
+0

Era un poco esperanzador para una forma sencilla de definir explícitamente una tabla temporal o algo así, pero eso definitivamente funcionaría – spaghetticowboy

+1

Este es un muy buen enfoque. Si crea dicha tabla con un registro por día en un marco de tiempo razonable, puede hacer todo tipo de cosas extrañas, como contabilizar los calendarios no estándar como emisión o fabricación/contabilidad, o registros asociados de grupo por días laborables, fines de semana y feriados. . – Olaf

+0

¿Existe una solución solo de consulta para este problema o es realmente necesario crear una tabla? – payling

4

básicamente donde es una forma pulida para obtener mi lista meses/mesa/lo que sea

Se puede utilizar una CTE recursiva para construir una lista de meses.

;with Months(MonthNum) as 
(
    select 1 MonthNum 
    union all 
    select MonthNum+1 
    from Months 
    where MonthNum < 12 
) 

-- Your query goes here 
select * 
from Months 
+0

Exactamente como lo he hecho antes, muy eficiente :) –

Cuestiones relacionadas