you can do this with a simple calendar table. in which you can have all the dates which you required. something like this
Note: I have used variable table for the demonstration purpose.
Declare @CalendarTable table
(
[DateKey] [int] NOT NULL,
[FullDateAlternateKey] [date] NOT NULL,
[DayNumberOfWeek] [tinyint] NOT NULL,
[EnglishDayNameOfWeek] [nvarchar](10) NULL,
[DayNumberOfMonth] [tinyint] NOT NULL,
[DayNumberOfYear] [smallint] NOT NULL,
[WeekNumberOfYear] [tinyint] NULL,
[EnglishMonthName] [nvarchar](10) NULL,
[MonthNumberOfYear] [tinyint] NOT NULL,
[CalendarQuarter] [tinyint] NOT NULL,
[CalendarYear] [smallint] NOT NULL,
[CalendarSemester] [tinyint] NULL
)
Declare @StartDate datetime
Declare @EndDate datetime
Select @StartDate = '20140101',
@EndDate = '20141231'
;WITH cTally
AS
(
select top 1100 ROW_NUMBER() Over (order by (select null)) - 1 as num
from syscolumns c
cross join syscolumns cc
)
INSERT INTO @CalendarTable(DateKey, FullDateAlternateKey, DayNumberOfWeek,
EnglishDayNameOfWeek, DayNumberOfMonth, DayNumberOfYear,
WeekNumberOfYear, EnglishMonthName, MonthNumberOfYear,
CalendarQuarter, CalendarYear)
SELECT
CONVERT(INT, CONVERT(nvarchar(12), DATEADD(dd,num,@StartDate), 112)),
DATEADD(dd,num,@StartDate),
DATEPART(dw, DATEADD(dd,num,@StartDate)),
DATENAME(dw, DATEADD(dd,num,@StartDate)),
DATEPART(dd, DATEADD(dd,num,@StartDate)),
DATEPART(dayofyear, DATEADD(dd,num,@StartDate)),
DATEPART(week, DATEADD(dd,num,@StartDate)),
DATENAME(MONTH, DATEADD(dd,num,@StartDate)),
DATEPART(mm, DATEADD(dd,num,@StartDate)),
DATEPART(qq, DATEADD(dd,num,@StartDate)),
DATEPART(yyyy, DATEADD(dd,num,@StartDate))
from cTally
Where DATEADD(dd,num,@StartDate) <= @EndDate
this is how you will use this. Let get your sample data in a proper format for better
readability.
Declare @Table1 table
(
owner_id varchar(10),
close_date datetime,
opp_id int
)
INSERT INTO @Table1
(
owner_id,
close_date,
opp_id
)
select 'Peter' , '2014-01-02 00:00:00.000', 1 union all
select 'Peter' , '2014-01-02 00:00:00.000', 2 union all
select 'Peter' , '2014-02-04 00:00:00.000', 3 union all
select 'Peter' , '2014-02-04 00:00:00.000', 4 union all
select 'Peter' , '2014-03-06 00:00:00.000', 5 union all
select 'Peter' , '2014-03-06 00:00:00.000', 6 union all
select 'Peter' , '2014-04-08 00:00:00.000', 7 union all
select 'Paul' , '2014-01-02 00:00:00.000', 8 union all
select 'Paul' , '2014-01-02 00:00:00.000', 9 union all
select 'Paul' , '2014-02-02 00:00:00.000', 10 union all
select 'Paul' , '2014-02-02 00:00:00.000', 11 union all
select 'Paul' , '2014-03-02 00:00:00.000', 12 union all
select 'Paul' , '2014-04-02 00:00:00.000', 13 union all
select 'Paul' , '2014-04-02 00:00:00.000', 14 union all
select 'Mary' , '2014-06-01 00:00:00.000', 15
Declare @Table2 table
(
opp_id int,
amtfinanced float
)
INSERT INTO @Table2
(
opp_id,
amtfinanced
)
select 1 , 2000.00 union all
select 2 , 12000.00 union all
select 3 , 12000.00 union all
select 4 , 13000.00 union all
select 5 , 14000.00 union all
select 6 , 15000.00 union all
select 7 , 16000.00 union all
select 8 , 12000.00 union all
select 9 , 13000.00 union all
select 10 , 14000.00 union all
select 11 , 15000.00 union all
select 12 , 16000.00 union all
select 13 , 17000.00 union all
select 14 , 18000.00 union all
select 15 , 1000000.00 union all
select 17 , 2000000.00
Here we can put things together.
;WITH CTE
AS
(
SELECT DISTINCT T1.owner_id, c.EnglishMonthName, c.CalendarYear, c.MonthNumberOfYear
FROM @CalendarTable C
CROSS JOIN @Table1 T1
)
SELECT C.owner_id, c.EnglishMonthName, c.CalendarYear, isnull(cpg.TOTA_amtfinanced,0) AS amtfinanced
FROM CTE C
LEFT JOIN (
SELECT t1.owner_id, datepart(mm,T1.close_date) as mon, datepart(yy,T1.close_date) as yr, SUM(T2.amtfinanced) AS TOTA_amtfinanced
FROM @Table1 t1
INNER JOIN @Table2 t2 on t1.opp_id = t2.opp_id
GROUP BY t1.owner_id,T1.close_date
) cpg on c.CalendarYear = cpg.yr
and c.MonthNumberOfYear = cpg.mon
and C.owner_id = cpg.owner_id
ORDER BY C.owner_id, c.CalendarYear, c.MonthNumberOfYear
hope it helps.
|