Search code examples
t-sqljoinaggregatemonthcalendar

Join and aggregate on two columns - for every month even months with no data?


Using SQL Server 2005.

I have a table with calendar months

Month,  fiscalorder
june,1
july,2
..
may,12

And another table with employees and a repeating monthly amount

employee, month, amount
john, july, 10
john, july, 3
john, august,2
mary, june, 2
mary, feb, 5

I need to join and aggregate these by month, but every month (even months without data) to report for every employe, but employee then fiscal order.

Output:

june, john, 0
july, john, 13
august,john,2
sept, john, 0
..
june,mary,2

Solution

  • Assuming Sql Server 2005+

    Declare @CalenderMonths Table ([Month] Varchar(20),FiscalOrder Int)
    
    Insert Into @CalenderMonths Values
    ('June',1),('July',2),('August',3),('September',4),('October',5),('November',6),
    ('December',7),('January',8),('February',9),('March',10),('April',11),('May', 12)
    
    Declare @Employee Table(employee varchar(50), [month] Varchar(20), amount int )
    Insert Into @Employee Values('john', 'July', 10),('john', 'July',3),('john','August',2),('mary','June',2),('mary', 'February',5)
    
    ;with cte as
    (
        Select employee,[month],TotalAmount = sum(amount)
        from @Employee
        group by employee,[month]
    )
    
    select x.[Month],x.employee,amount = coalesce(c.TotalAmount,0)
    from (
    select distinct c.[Month],e.employee
    from @CalenderMonths c cross join cte e)x
    left join cte c on x.[Month] = c.[Month] and x.employee = c.employee
    order by 2