这适用于SQL Server 2008/2012。
我有以下数据集,其中包含声明开始日期和结束日期。我想计算背靠背索赔的天数,其中下一个日期的索赔开始日期是在上一个日期的索赔结束日期之后的一天,使其成为连续服务。
如果服务中断,例如05/15的索赔结束和05/18开始的会员ID 1002,计数应该重新启动。
MemberID Claim Start Claim End Claim_ID
1001 2016-04-01 2016-04-15 ABC11111
1001 2016-04-16 2016-04-30 ABC65465
1001 2016-05-01 2016-05-15 ABC51651
1001 2016-05-16 2016-06-15 ABC76320
1002 2016-04-01 2016-04-15 ABC74563
1002 2016-04-16 2016-04-30 ABC02123
1002 2016-05-01 2016-05-15 ABC02223
1002 2016-05-18 2016-06-15 ABC66632
1002 2016-06-16 2016-06-30 ABC77447
1002 2016-07-10 2016-07-31 ABC33221
1002 2016-08-01 2016-08-10 ABC88877
如此有效,我想要以下输出。在第一个索赔开始日期的最小值,索赔结束日期的最大值,此时多个索赔之间的保险范围没有差距。如果覆盖范围存在差距,则计数重新开始,第一个索赔的开始日期的最小值和索赔结束日期的最大值,直到多个索赔之间的覆盖范围没有差距。
MemberID Claim_Start Claim_End Continuous_Service_Days
1001 2016-04-01 2016-06-15 76
1002 2016-04-01 2016-05-15 45
1002 2016-05-18 2016-06-30 44
1002 2016-07-10 2016-08-10 32
我尝试了while循环,CTE&s,我也尝试了下表,首先获得声明之间的所有日期。但我在计算连续日期之间的天数方面遇到问题,如果覆盖范围中断,则重置计数。
Master.dbo.spt_values
感谢任何帮助。谢谢!
答案 0 :(得分:2)
您需要先找到差距。
此解决方案使用Tally Table生成从ClaimStart
到ClaimEnd
的日期。然后使用生成的日期,使用this method获取差距。
现在您已经有了差距,现在可以使用GROUP BY
来MIN(ClaimStart
)和MAX(ClaimStart)
:
WITH E1(N) AS( -- 10 ^ 1 = 10 rows
SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10 ^ 2 = 100 rows
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10 ^ 4 = 10,000 rows
CteTally(N) AS(
SELECT TOP(SELECT MAX(DATEDIFF(DAY, ClaimStart, ClaimEnd) + 1) FROM tbl)
ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
FROM E4
),
CteDates AS( -- Generate the dates from ClaimStart to ClaimEnd
SELECT
t.MemberID,
dt = DATEADD(DAY, ct.N - 1, t.ClaimStart)
FROM tbl t
INNER JOIN CteTally ct
ON DATEADD(DAY, ct.N - 1, t.ClaimStart) <= t.ClaimEnd
),
CteGrp AS( -- Find gaps and continuous dates
SELECT *,
rn = DATEADD(DAY, - ROW_NUMBER() OVER(PARTITION BY MemberID ORDER BY dt), dt)
FROM CteDates
)
SELECT
MemberID,
ClaimStart = MIN(dt),
ClaimEnd = MAX(dt),
Diff = DATEDIFF(DAY, MIN(dt), MAX(dt)) + 1
FROM CteGrp
GROUP BY MemberID, rn
ORDER BY MemberID, ClaimStart;
答案 1 :(得分:1)
void *j;
cudaMalloc(&j, sizeof(int*)*N); // stores result in j
int **devicePointersStoredInDeviceMemory = (int **) j;
返回
Declare @YourTable table (MemberID int,[Claim Start] date,[Claim End] date,[Claim_ID] varchar(25))
Insert Into @YourTable values
(1001,'2016-04-01','2016-04-15','ABC11111'),
(1001,'2016-04-16','2016-04-30','ABC65465'),
(1001,'2016-05-01','2016-05-15','ABC51651'),
(1001,'2016-05-16','2016-06-15','ABC76320'),
(1002,'2016-04-01','2016-04-15','ABC74563'),
(1002,'2016-04-16','2016-04-30','ABC02123'),
(1002,'2016-05-01','2016-05-15','ABC02223'),
(1002,'2016-05-18','2016-06-15','ABC66632'),
(1002,'2016-06-16','2016-06-30','ABC77447'),
(1002,'2016-07-10','2016-07-31','ABC33221'),
(1002,'2016-08-01','2016-08-10','ABC88877')
;with cte0(N) as (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N))
,cte1(R,D) as (Select Row_Number() over (Order By (Select Null))
,DateAdd(DD,-1+Row_Number() over (Order By (Select Null)),(Select MinDate=min([Claim Start]) From @YourTable))
From cte0 N1, cte0 N2, cte0 N3, cte0 N4)
Select MemberID
,[Claim Start] = Min([Claim Start])
,[Claim End] = Max([Claim End])
,Continuous_Service_Days = count(*)
From (
Select *,Island = R - Row_Number() over (Partition By MemberID Order by [Claim Start])
From @YourTable A
Join cte1 B on D Between [Claim Start] and [Claim End]
) A
Group By MemberID,Island
Order By 1,2