SQL Stairstep Query
Since you are using SQL Server 2012, we can use the Format function to make the date pretty. There is no need to group by the strings. Instead, I find it useful to use the proper data type for as long as I can and only use Format or Convert on display (or not at all and let the middle tier handle the display).
In this solution, I arbitrarily assumed the earliest TransDate and extract from it, the first day of that month. However, one could easily replace that expression with a static value of the start date desired and this solution would take that and the next 12 months.
With SubmissionMonths As ( Select DateAdd(d, -Day(A.SubmissionDate) + 1, A.SubmissionDate) As SubmissionMonth , A.Amount From dbo.Accounts As A ) , TranMonths As ( Select DateAdd(d, -Day(Min( T.TranDate )) + 1, Min( T.TranDate )) As TranMonth , 1 As MonthNum From dbo.Accounts As A Join dbo.Trans As T On T.AccountId = A.AccountId Join SubmissionMonths As M On A.SubmissionDate >= M.SubmissionMonth And A.SubmissionDate < DateAdd(m,1,SubmissionMonth) Union All Select DateAdd(m, 1, TranMonth), MonthNum + 1 From TranMonths Where MonthNum < 12 ) , TotalBySubmissionMonth As ( Select M.SubmissionMonth, Sum( M.Amount ) As Total From SubmissionMonths As M Group By M.SubmissionMonth )Select Format(SMT.SubmissionMonth,'yyyy-MM') As SubmissionMonth, SMT.Total , Sum( Case When TM.MonthNum = 1 Then T.TranAmount End ) As Month1 , Sum( Case When TM.MonthNum = 2 Then T.TranAmount End ) As Month2 , Sum( Case When TM.MonthNum = 3 Then T.TranAmount End ) As Month3 , Sum( Case When TM.MonthNum = 4 Then T.TranAmount End ) As Month4 , Sum( Case When TM.MonthNum = 5 Then T.TranAmount End ) As Month5 , Sum( Case When TM.MonthNum = 6 Then T.TranAmount End ) As Month6 , Sum( Case When TM.MonthNum = 7 Then T.TranAmount End ) As Month7 , Sum( Case When TM.MonthNum = 8 Then T.TranAmount End ) As Month8 , Sum( Case When TM.MonthNum = 9 Then T.TranAmount End ) As Month9 , Sum( Case When TM.MonthNum = 10 Then T.TranAmount End ) As Month10 , Sum( Case When TM.MonthNum = 11 Then T.TranAmount End ) As Month11 , Sum( Case When TM.MonthNum = 12 Then T.TranAmount End ) As Month12From TotalBySubmissionMonth As SMT Join dbo.Accounts As A On A.SubmissionDate >= SMT.SubmissionMonth And A.SubmissionDate < DateAdd(m,1,SMT.SubmissionMonth) Join dbo.Trans As T On T.AccountId = A.AccountId Join TranMonths As TM On T.TranDate >= TM.TranMonth And T.TranDate < DateAdd(m,1,TM.TranMonth)Group By SMT.SubmissionMonth, SMT.Total
The following query pretty much returns what you want. You need to do the to operations separately. I just join the results together:
select a.yyyymm, a.Amount, t201201, t201202, t201203, t201204 from (select LEFT(convert(varchar(255), a.submissiondate, 121), 7) as yyyymm, SUM(a.Amount) as amount from Accounts a group by LEFT(convert(varchar(255), a.submissiondate, 121), 7) ) a left outer join (select LEFT(convert(varchar(255), a.submissiondate, 121), 7) as yyyymm, sum(case when trans_yyyymm = '2012-01' then tranamount end) as t201201, sum(case when trans_yyyymm = '2012-02' then tranamount end) as t201202, sum(case when trans_yyyymm = '2012-03' then tranamount end) as t201203, sum(case when trans_yyyymm = '2012-04' then tranamount end) as t201204 from Accounts a join (select t.*, LEFT(convert(varchar(255), t.trandate, 121), 7) as trans_yyyymm from trans t ) t on a.accountid = t.accountid group by LEFT(convert(varchar(255), a.submissiondate, 121), 7) ) t on a.yyyymm = t.yyyymm order by 1
I am getting a NULL where you have a 0.00 in two cells.
Thomas, I used your response as inspiration for the following solution I ended up using.
I first create a SubmissionDate, TranDate cross join skeleton date matrix, that I later use to join on the AccountSummary and TranSummary data.
The resulting query output isn't formatted in columns, per TranDate month. Rather I'm using output in a SQL Server Reporting Services matrix, and using a column grouping, based off the TranSummaryMonthNum column, to get the desired formatted output.
;WITH --Generate a list of Dates, from the first SubmissionDate, through today. --Note: Requires the use of: 'OPTION (MAXRECURSION 0)' to generate a list with more than 100 dates. CTE_AutoDates AS ( Select Min(SubmissionDate) as FiscalDate From Accounts UNION ALL SELECT DATEADD(Day, 1, FiscalDate) FROM CTE_AutoDates WHERE DATEADD(Day, 1, FiscalDate) <= GetDate() ), FiscalDates As ( SELECT FiscalDate, DATEFROMPARTS(Year(FiscalDate), Month(FiscalDate), 1) as FiscalMonthStartDate FROM CTE_AutoDates --Optionaly filter Fiscal Dates by the last known Math.Max(SubmissionDate, TranDate) Where FiscalDate <= (Select Max(MaxDate) From (Select Max(SubmissionDate) as MaxDate From Accounts Union All Select Max(TranDate) as MaxDate From Trans ) as MaxDates ) ), FiscalMonths as ( SELECT Distinct FiscalMonthStartDate FROM FiscalDates ), --Matrix to store the reporting date groupings for the Account submission and payment periods. SubmissionAndTranMonths AS ( Select AM.FiscalMonthStartDate as SubmissionMonthStartDate, TM.FiscalMonthStartDate as TransMonthStartDate, DateDiff(Month, (Select Min(FiscalMonthStartDate) From FiscalMonths), TM.FiscalMonthStartDate) as TranSummaryMonthNum From FiscalMonths AS AM Join FiscalMonths AS TM ON TM.FiscalMonthStartDate >= AM.FiscalMonthStartDate ), AccountData as ( Select A.AccountID, A.Amount, FD.FiscalMonthStartDate as SubmissionMonthStartDate From Accounts as A Inner Join FiscalDates as FD ON A.SubmissionDate = FD.FiscalDate ), TranData as ( Select T.AccountID, T.TranAmount, AD.SubmissionMonthStartDate, FD.FiscalMonthStartDate as TranMonthStartDate From Trans as T Inner Join AccountData as AD ON T.AccountID = AD.AccountID Inner Join FiscalDates AS FD ON T.TranDate = FD.FiscalDate ), AccountSummaryByMonth As ( Select ASM.FiscalMonthStartDate, Sum(AD.Amount) as TotalSubmissionAmount From FiscalMonths as ASM Inner Join AccountData as AD ON ASM.FiscalMonthStartDate = AD.SubmissionMonthStartDate Group By ASM.FiscalMonthStartDate ), TranSummaryByMonth As ( Select STM.SubmissionMonthStartDate, STM.TransMonthStartDate, STM.TranSummaryMonthNum, Sum(TD.TranAmount) as TotalTranAmount From SubmissionAndTranMonths as STM Inner Join TranData as TD ON STM.SubmissionMonthStartDate = TD.SubmissionMonthStartDate AND STM.TransMonthStartDate = TD.TranMonthStartDate Group By STM.SubmissionMonthStartDate, STM.TransMonthStartDate, STM.TranSummaryMonthNum )--#Inspect 1--Select * From SubmissionAndTranMonths--OPTION (MAXRECURSION 0)--#Inspect 1 Results--SubmissionMonthStartDate TransMonthStartDate TranSummaryMonthNum--2012-01-01 2012-01-01 0--2012-01-01 2012-02-01 1--2012-01-01 2012-03-01 2--2012-01-01 2012-04-01 3--2012-02-01 2012-02-01 1--2012-02-01 2012-03-01 2--2012-02-01 2012-04-01 3--2012-03-01 2012-03-01 2--2012-03-01 2012-04-01 3--2012-04-01 2012-04-01 3--#Inspect 2--Select * From AccountSummaryByMonth--OPTION (MAXRECURSION 0)--#Inspect 2 Results--FiscalMonthStartDate TotalSubmissionAmount--2012-01-01 2099.00--2012-02-01 350.00--2012-03-01 685.00--#Inspect 3--Select * From TranSummaryByMonth--OPTION (MAXRECURSION 0)--#Inspect 3 Results--SubmissionMonthStartDate TransMonthStartDate TranSummaryMonthNum TotalTranAmount--2012-01-01 2012-01-01 0 300.00--2012-01-01 2012-02-01 1 300.00--2012-01-01 2012-03-01 2 300.00--2012-02-01 2012-02-01 1 325.00--2012-02-01 2012-04-01 3 25.00--2012-03-01 2012-03-01 2 656.00--2012-03-01 2012-04-01 3 15.00Select STM.SubmissionMonthStartDate, ASM.TotalSubmissionAmount, STM.TransMonthStartDate, STM.TranSummaryMonthNum, TSM.TotalTranAmountFrom SubmissionAndTranMonths as STM Inner Join AccountSummaryByMonth as ASM ON STM.SubmissionMonthStartDate = ASM.FiscalMonthStartDate Left Join TranSummaryByMonth AS TSM ON STM.SubmissionMonthStartDate = TSM.SubmissionMonthStartDate AND STM.TransMonthStartDate = TSM.TransMonthStartDateOrder By STM.SubmissionMonthStartDate, STM.TranSummaryMonthNumOPTION (MAXRECURSION 0)--#Results--SubmissionMonthStartDate TotalSubmissionAmount TransMonthStartDate TranSummaryMonthNum TotalTranAmount--2012-01-01 2099.00 2012-01-01 0 300.00--2012-01-01 2099.00 2012-02-01 1 300.00--2012-01-01 2099.00 2012-03-01 2 300.00--2012-01-01 2099.00 2012-04-01 3 NULL--2012-02-01 350.00 2012-02-01 1 325.00--2012-02-01 350.00 2012-03-01 2 NULL--2012-02-01 350.00 2012-04-01 3 25.00--2012-03-01 685.00 2012-03-01 2 656.00--2012-03-01 685.00 2012-04-01 3 15.00