我在一个表中有 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 回答