我在一个表中有 4 列 `BenefitKey、MemberKey、StartDate、Enddate`
给定这样的数据:
开始日期 结束日期
------------------------------
20110315 20110316
20110317 20110320
20110321 20110325
20110326 20121202
20121203 20121210
20121211 20121215
20121225 20121231
我需要找到 12 月份之间的缺失差距并使用 SQL 查询来填补空白
这里缺少的差距是从“20121216”到“20121224”。我有 1000 行这样的行,所以我需要一个 SQL 查询。我找到了一些解决方案,但仍然不正确,这是我写的
创建表 #BenfitDim(成员名称 varchar(30),成员密钥 int,成员有效日期日期时间,成员终止日期日期时间)
插入 #BenfitDim 值('tom',231,'2012-11-18','2012-11-23')
插入 #BenfitDim 值('tom',231,'2012-11-24','2012-12-12')
插入 #BenfitDim 值('tom',231,'2013-01-01','2999-12-12')
插入 #BenfitDim 值('jack',344,'2011-06-27','2012-12-07')
插入 #BenfitDim 值('jack',344,'2012-12-01','2015-12-31')
插入 #BenfitDim 值('nick',243,'2012-12-01','2012-12-07')
插入 #BenfitDim 值('joy',234,'2012-12-08','2012-12-14')
插入 #BenfitDim 值('tim',364,'2012-12-25','2012-12-30')
插入 #BenfitDim 值('tim',364,'2013-01-15','2013-01-30')
插入 #BenfitDim 值('杰瑞',365,'2011-9-15','2012-12-31')
插入 #BenfitDim 值('杰瑞',365,'2013-01-15','2013-01-30')
插入 #BenfitDim 值('杰瑞',365,'2011-01-15','2012-01-30')
选择会员密钥,
成员名字,
DATEADD(DAY,1,T1.MemberTerminationDate)AS MemberEffectiveDate,
DATEADD(DAY,-1,D.MemberEffectiveDate)AS MemberTerminationDate
从
#BenfitDim AS T1 交叉申请(
SELECT MIN(MemberEffectiveDate)AS MemberEffectiveDate
来自#BenfitDim AS T
WHERE T.MemberEffectiveDate > T1.MemberEffectiveDate
AND T.MemberKey = T1.MemberKey)D
WHERE DATEADD(DAY,1,T1.MemberTerminationDate) D.MemberEffectiveDate
执行后,您会发现丢失的序列,但仍然存在一个小问题,我们如何处理表中“jack”的重叠数据并正确获取丢失的序列。
2966 次
4 回答
0
你有一张包含完整年份日期的表格吗?如果没有,您需要创建一个来查找缺失的日期。否则,您可以使用非常慢的游标。
于 2013-01-28T15:52:55.067 回答
0
如果您的数据具有这种格式且没有重叠,那么以下查询将为您提供两个日期之间的间隔:
select enddate+1 as startdate,
(select MIN(startdate) - 1 from t t2 where t2.startdate > t.enddate
) as enddate
from t
where enddate+1 not in (select startdate from t)
我在这里使用相关子查询,因为在我看来,它使查询的结构更清晰。间隔enddate+1在下一个开始日期前一天开始并结束。enddate+1并且,当它本身不是开始日期时,只有一个间隙。
如果这产生了正确的结果,那么您可以使用以下方法将这些值插入到您的表中:
insert into t(startdate, enddate)
select enddate+1 as startdate,
(select MIN(startdate) - 1 from t t2 where t2.startdate > t.enddate
) as enddate
from t
where enddate+1 not in (select startdate from t)
于 2013-01-28T16:49:09.963 回答
0
假设您的表名为“Benefits”。
沿着这条线的东西会解决你的问题吗?
SELECT A.EndDate + 1 AS GapFrom,
(SELECT MIN(StartDate) - 1
FROM Benefits WHERE StartDate > A.EndDate) AS GapUntil
FROM Benefits A
LEFT JOIN Benefits B WHERE A.EndDate + 1 = B.StartDate
WHERE B.BenefitKey IS NULL
于 2013-01-28T15:57:44.873 回答
0
您想要做的是一个自我加入,您将在其中加入先前的记录,例如:
SELECT …,startDate, endDate
FROM Table t, Table t2
WHERE t2.id=t1.id+1
(这假设 ID 是连续的,如果不是,则执行以下操作:
WHERE t1.enddate < MIN(t1.startdate)
这应该让您按日期顺序获得下一条记录。
然后堵住这个洞很简单:
INSERT INTO table
VALUES blah, blah, t.endDate+1, t2.startDate-1
(日期上的伪代码,您必须使用您的版本支持的任何功能进行数学运算,例如 DATEADD。)
于 2013-01-28T15:59:18.790 回答