这是一个示例,说明如何使用 a 构建日历CTE
并使用OVER(PARTION BY)
询问:
-- Declare a Start and End Date required to build a calendar
DECLARE @StartDate DATETIME = '2013-01-01'
DECLARE @EndDate DATETIME = '2015-01-01'
-- Build out a Day/Quarter Calendar
;WITH Calendar ([Date], [Quarter]) AS (
SELECT @StartDate, 1
UNION ALL
SELECT [Date] + 1, (DATEDIFF(m, @StartDate, [Date] + 1) / 3) + 1
FROM Calendar
WHERE [Date] + 1 < @EndDate
)
-- Build Result Set
SELECT ProgramName,
DateFilled,
DaySupply,
MemberID,
Strength,
Quarter,
SUM(Strength) OVER(PARTITION BY ProgramName, DaySupply, MemberID, Quarter) AS QuarterlyTotal,
AVG(Strength) OVER(PARTITION BY ProgramName, DaySupply, MemberID, Quarter) AS QuarterlyAverage
FROM #MemberInfo MI
JOIN Calendar C ON MI.DateFilled = C.[Date]
ORDER BY MemberID, DateFilled
OPTION (MAXRECURSION 0)
测试数据:
create table #MemberInfo
(ProgramName varchar(255),
DateFilled datetime,
DaySupply integer,
MemberID varchar(255),
Strength integer,
Tradename varchar(255));
INSERT INTO #MemberInfo
Values
--MEM001
--Q1
('InsureCo', '20130112', 30, 'MEM001', 10, 'Sedative')
,('InsureCo', '20130129', 30, 'MEM001', 20, 'Sedative')
,('InsureCo', '20130401', 30, 'MEM001', 20, 'Sedative')
--Q2
,('InsureCo', '20130529', 30, 'MEM001', 30, 'Sedative')
,('InsureCo', '20130429', 30, 'MEM001', 20, 'Sedative')
,('InsureCo', '20130401', 30, 'MEM001', 20, 'Sedative')
--Q3
,('InsureCo', '20130829', 30, 'MEM001', 30, 'Sedative')
--MEM002
--Q1
,('InsureCo', '20130112', 30, 'MEM002', 10, 'Sedative')
,('InsureCo', '20130129', 30, 'MEM002', 20, 'Sedative')
,('InsureCo', '20130401', 30, 'MEM002', 20, 'Sedative')
--Q2
,('InsureCo', '20130529', 30, 'MEM002', 30, 'Sedative')
,('InsureCo', '20130429', 30, 'MEM002', 20, 'Sedative')
,('InsureCo', '20130401', 30, 'MEM002', 20, 'Sedative')
--Q3
,('InsureCo', '20130829', 30, 'MEM002', 30, 'Sedative')
--Q4
,('InsureCo', '20131129', 30, 'MEM002', 30, 'Sedative')
结果:
ProgramName DateFilled DaySupply MemberID Strength Quarter QuarterlyTotal QuarterlyAverage
InsureCo 2013-01-12 30 MEM001 10 1 30 15
InsureCo 2013-01-29 30 MEM001 20 1 30 15
InsureCo 2013-04-01 30 MEM001 20 2 90 22
InsureCo 2013-04-01 30 MEM001 20 2 90 22
InsureCo 2013-04-29 30 MEM001 20 2 90 22
InsureCo 2013-05-29 30 MEM001 30 2 90 22
InsureCo 2013-08-29 30 MEM001 30 3 30 30
InsureCo 2013-01-12 30 MEM002 10 1 30 15
InsureCo 2013-01-29 30 MEM002 20 1 30 15
InsureCo 2013-04-01 30 MEM002 20 2 90 22
InsureCo 2013-04-01 30 MEM002 20 2 90 22
InsureCo 2013-04-29 30 MEM002 20 2 90 22
InsureCo 2013-05-29 30 MEM002 30 2 90 22
InsureCo 2013-08-29 30 MEM002 30 3 30 30
InsureCo 2013-11-29 30 MEM002 30 4 30 30