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 .
Do you have a table that has a complete year of dates? If not, you need to create one to find missing dates. Otherwise, you can use a cursor which would be very slow.
Say your table is named "Benefits".
Would something along this line solve your problem?
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
What you want to do is a self join where you are joining the prior record, something like:
SELECT …,startDate, endDate
FROM Table t, Table t2
WHERE t2.id=t1.id+1
(this assumes IDs are sequential, if not then do:
WHERE t1.enddate < MIN(t1.startdate)
this should get you the next record in date sequence.
Then to plug the hole it's a simple matter of:
INSERT INTO table
VALUES blah, blah, t.endDate+1, t2.startDate-1
(Pseudocode on the dates, you'll have to do the math with whatever functions your version supports, like DATEADD.)
If you data has this format, with no overlaps, then the following query gets you the gaps between two dates:
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)
I'm using a correlated subquery here because, in my opinion, it makes the structure of the query clearer. The gap starts at enddate+1
and ends one day before the next start date. And, there is only a gap when enddate+1
is not itself a startdate.
If this is producing correct results, then you can insert these values into your table using:
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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.