1
我在一个表中有 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”的重叠数据并正确获取丢失的序列。


4

4 回答 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 回答