查找特定月份的sql中日期之间的差距

时间:2013-01-28 15:52:01

标签: sql sql-server tsql

I have 4 columns `BenefitKey, MemberKey, StartDate, Enddate` in a table

Given data like this:

    StartDate         Enddate
    ------------------------------
    20110315           20110316 
    20110317           20110320
    20110321           20110325
    20110326           20121202
    20121203           20121210
    20121211           20121215
    20121225           20121231

I need to find the missing gap between the month of December and fill the gap using a SQL query 

Here the missing gap is from `20121216` to `20121224`. I have 1000 rows like this, so I need a SQL query .i found some solution to it but still not correct here is what i wrote
CREATE TABLE #BenfitDim(MemberName varchar(30),Memberkey int,MemberEffectiveDate DATETIME, MemberTerminationDate DATETIME)


    INSERT INTO #BenfitDim VALUES('tom',231,'2012-11-18','2012-11-23')
    INSERT INTO #BenfitDim VALUES('tom',231,'2012-11-24','2012-12-12')
    INSERT INTO #BenfitDim VALUES('tom',231,'2013-01-01','2999-12-12')
    INSERT INTO #BenfitDim VALUES('jack',344,'2011-06-27','2012-12-07') 
    INSERT INTO #BenfitDim VALUES('jack',344,'2012-12-01','2015-12-31')
    INSERT INTO #BenfitDim VALUES('nick',243,'2012-12-01','2012-12-07')
    INSERT INTO #BenfitDim VALUES('joy',234,'2012-12-08','2012-12-14')
    INSERT INTO #BenfitDim VALUES('tim',364,'2012-12-25','2012-12-30')
    INSERT INTO #BenfitDim VALUES('tim',364,'2013-01-15','2013-01-30')
    INSERT INTO #BenfitDim VALUES('jerry',365,'2011-9-15','2012-12-31')
    INSERT INTO #BenfitDim VALUES('jerry',365,'2013-01-15','2013-01-30')
    INSERT INTO #BenfitDim VALUES('jerry',365,'2011-01-15','2012-01-30')




    SELECT MemberKey,
           MemberName,
           DATEADD(DAY,1,T1.MemberTerminationDate)AS MemberEffectiveDate,
           DATEADD(DAY,-1,D.MemberEffectiveDate)AS MemberTerminationDate
    FROM
           #BenfitDim AS T1 CROSS APPLY(
                                    SELECT MIN(MemberEffectiveDate)AS MemberEffectiveDate
                                      FROM #BenfitDim AS T
                                      WHERE T.MemberEffectiveDate > T1.MemberEffectiveDate 
                                      AND T.MemberKey = T1.MemberKey)D
     WHERE DATEADD(DAY,1,T1.MemberTerminationDate)  D.MemberEffectiveDate



Once you execute you will find the missing sequence but still there is slight problem how do we take care of an overlap data of "jack" in the table and get the missing sequence right .


4 个答案:

答案 0 :(得分:0)

你有一张完整的约会年份表吗?如果没有,您需要创建一个以查找缺少的日期。否则,您可以使用非常慢的光标。

答案 1 :(得分:0)

假设您的表名为“好处”。

沿着这条线会解决你的问题吗?

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

答案 2 :(得分: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。)

答案 3 :(得分: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)