Author |
Topic |
DonAtWork
Master Smack Fu Yak Hacker
2167 Posts |
Posted - 2008-09-29 : 09:49:50
|
Ok. Working with SQL 2000Asked about this on 2k5, but it never quite worked. That is neither here nor there. The problem: I have a bunch of records that need to be merged by certain criteria.If the consultantid and employerid of one record match the same on another record, i need to compare the sd and ed (startdate and enddate).IF they overlap(the startdate of record#2 is equal to the startdate of record#1, or the startdate of a record#2 falls within the date range of the startdate and enddate of record#1),then they get merged (min startdate and max end date).Also, if they are contiguous(e.g. record#1 ends on 12/31/2000, and record#2 starts on 1/1/2001), the get merged in the same way.Otherwise, they will stay as separate records.I can most likely do this with a loop, but there must be a way to do it set based.again, I am on SQL 2000. Here is the sample input, and expected output:declare @yak table (poaid int, consultantid int, employerid int,sd datetime,ed datetime)insert into @yak(poaid,consultantid,employerid,sd,ed)select 1790,1,225,'1999-01-01 00:00:00.000','2001-12-31 00:00:00.000'union all select 1791,1,225,'2003-01-01 00:00:00.000','2007-12-31 00:00:00.000'union all select 21,1,276,'1999-01-01 00:00:00.000','2002-12-31 00:00:00.000'union all select 22,1,276,'2000-01-01 00:00:00.000','2002-12-31 00:00:00.000'union all select 1815,1,599,'1999-01-01 00:00:00.000','2004-12-31 00:00:00.000'union all select 4479,1,599,'2007-01-01 00:00:00.000','2009-12-31 00:00:00.000'union all select 1084,16,6588,'1996-10-01 00:00:00.000','2006-09-30 00:00:00.000'union all select 4584,16,6588,'2007-10-01 00:00:00.000','2008-09-30 00:00:00.000'union all select 1100,21,167,'1996-10-01 00:00:00.000','1998-12-31 00:00:00.000'union all select 1101,21,167,'1997-01-01 00:00:00.000','1999-12-31 00:00:00.000'union all select 1103,21,270,'1996-10-01 00:00:00.000','2002-12-31 00:00:00.000'union all select 1104,21,270,'1996-10-01 00:00:00.000','2009-12-31 00:00:00.000'union all select 1415,30,4123,'1996-10-01 00:00:00.000','2002-12-31 00:00:00.000'union all select 1416,30,4123,'2003-01-01 00:00:00.000','2005-01-01 00:00:00.000'Expected output:poaid c_id e_id sd ed1790 1 225 1999-01-01 00:00:00.000 2001-12-31 00:00:00.0001791 1 225 2003-01-01 00:00:00.000 2007-12-31 00:00:00.00021 1 276 1999-01-01 00:00:00.000 2002-12-31 00:00:00.0001815 1 599 1999-01-01 00:00:00.000 2004-12-31 00:00:00.0004479 1 599 2007-01-01 00:00:00.000 2009-12-31 00:00:00.0001084 16 6588 1996-10-01 00:00:00.000 2006-09-30 00:00:00.0004584 16 6588 2007-10-01 00:00:00.000 2008-09-30 00:00:00.0001100 21 167 1996-10-01 00:00:00.000 1999-12-31 00:00:00.0001103 21 270 1996-10-01 00:00:00.000 2009-12-31 00:00:00.0001415 30 4123 1996-10-01 00:00:00.000 2005-01-01 00:00:00.000 record 22 merged into 21, 1104 merged into 1103record 1415 merged into 1416 because they are contiguous.[Signature]For fast help, follow this link:http://weblogs.sqlteam.com/brettk/archive/2005/05/25.aspxLearn SQL or How to sell Used CarsFor ultra basic questions, follow these links.http://www.sql-tutorial.net/ http://www.firstsql.com/tutor.htm http://www.w3schools.com/sql/default.asp |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-09-29 : 11:12:54
|
[code]SELECT MIN(poaid) AS poaid,consultantid,employerid,MIN(sd) AS sd,MAX(ed) AS edFROM(SELECT *,(SELECT MAX(poaid) FROM @yakWHERE consultantid=y.consultantidAND employerid=y.employeridAND (sd<y.ed OR DATEDIFF(dd,y.ed,sd)=1)AND ed>y.sdAND poaid>y.poaid) AS MaxSeqFROM @yak y)tGROUP BY t.consultantid,t.employerid,t.MaxSeq[/code] |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-09-29 : 11:55:39
|
[code]declare @yak table (poaid int, consultantid int, employerid int,sd datetime,ed datetime,primary key clustered (consultantid, employerid,sd, ed), seq int)insert into @yak(poaid,consultantid,employerid,sd,ed)select 1790,1,225,'1999-01-01 00:00:00.000','2001-12-31 00:00:00.000'union all select 1791,1,225,'2003-01-01 00:00:00.000','2007-12-31 00:00:00.000'union all select 21,1,276,'1999-01-01 00:00:00.000','2002-12-31 00:00:00.000'union all select 22,1,276,'2000-01-01 00:00:00.000','2002-12-31 00:00:00.000'union all select 1815,1,599,'1999-01-01 00:00:00.000','2004-12-31 00:00:00.000'union all select 4479,1,599,'2007-01-01 00:00:00.000','2009-12-31 00:00:00.000'union all select 1084,16,6588,'1996-10-01 00:00:00.000','2006-09-30 00:00:00.000'union all select 4584,16,6588,'2007-10-01 00:00:00.000','2008-09-30 00:00:00.000'union all select 1100,21,167,'1996-10-01 00:00:00.000','1998-12-31 00:00:00.000'union all select 1101,21,167,'1997-01-01 00:00:00.000','1999-12-31 00:00:00.000'union all select 1103,21,270,'1996-10-01 00:00:00.000','2002-12-31 00:00:00.000'union all select 1104,21,270,'1996-10-01 00:00:00.000','2009-12-31 00:00:00.000'union all select 1415,30,4123,'1996-10-01 00:00:00.000','2002-12-31 00:00:00.000'union all select 1416,30,4123,'2003-01-01 00:00:00.000','2005-01-01 00:00:00.000'DECLARE @Seq INT, @cid int, @eid int, @sd DATETIME, @ed DATETIME SELECT TOP 1 @Seq = 0, @cid= consultantid, @eid = employerid, @sd = sd, @ed = edFROM @yakORDER BY consultantid, employerid, sd, edUPDATE @yakSET @Seq = CASE WHEN sd > @ed + 1 THEN @Seq + 1 WHEN consultantid > @cid THEN @Seq + 1 WHEN employerid > @eid THEN @Seq + 1 ELSE @Seq END, @sd = CASE WHEN ed > @ed THEN sd WHEN consultantid > @cid THEN sd WHEN employerid > @eid THEN sd ELSE @sd END, @ed= CASE WHEN ed > @ed THEN ed WHEN consultantid > @cid THEN ed WHEN employerid > @eid THEN ed ELSE @ed END, Seq = @Seq, @cid = consultantid,@eid = employeridSELECT consultantid, employerid, MIN(sd) AS DateFrom, MAX(ed) AS DateToFROM @yakGROUP BY consultantid, employerid, SeqORDER BY Seq[/code] E 12°55'05.63"N 56°04'39.26" |
|
|
DonAtWork
Master Smack Fu Yak Hacker
2167 Posts |
Posted - 2008-09-29 : 12:35:07
|
Visakh: That still does not work. It still does a simple min and max, without regard to weather the dates intersect or not. Thanks for the effort though.Peso: Very, very nice. Wish I had access to the weblogs here at work, but they block them. Your code works like a charm. Slight tweaking on my end and I should be set! (I didn't give you guys the WHOLE picture, just the part that was vexing me). Thank you very much![Signature]For fast help, follow this link:http://weblogs.sqlteam.com/brettk/archive/2005/05/25.aspxLearn SQL or How to sell Used CarsFor ultra basic questions, follow these links.http://www.sql-tutorial.net/ http://www.firstsql.com/tutor.htm http://www.w3schools.com/sql/default.asp |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-09-29 : 14:37:12
|
Just make sure you use "not equal to <>" instead of "greater than >". E 12°55'05.63"N 56°04'39.26" |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-09-29 : 23:56:03
|
quote: Originally posted by DonAtWork Visakh: That still does not work. It still does a simple min and max, without regard to weather the dates intersect or not. Thanks for the effort though.Peso: Very, very nice. Wish I had access to the weblogs here at work, but they block them. Your code works like a charm. Slight tweaking on my end and I should be set! (I didn't give you guys the WHOLE picture, just the part that was vexing me). Thank you very much![Signature]For fast help, follow this link:http://weblogs.sqlteam.com/brettk/archive/2005/05/25.aspxLearn SQL or How to sell Used CarsFor ultra basic questions, follow these links.http://www.sql-tutorial.net/ http://www.firstsql.com/tutor.htm http://www.w3schools.com/sql/default.asp
actually it needed a small tweakSELECT MIN(poaid) AS poaid,consultantid,employerid,MIN(sd) AS sd,MAX(ed) AS edFROM(SELECT *,(SELECT MAX(poaid) FROM @yakWHERE consultantid=y.consultantidAND employerid=y.employeridAND (sd<y.ed OR DATEDIFF(dd,y.ed,sd)=1)AND ed>y.sdAND poaid>=y.poaid) AS MaxSeqFROM @yak y)tGROUP BY t.consultantid,t.employerid,t.MaxSeqoutput---------------------------------poaid consultantid employerid sd ed----------- ------------ ----------- ----------------------- -----------------------1790 1 225 1999-01-01 00:00:00.000 2001-12-31 00:00:00.0001791 1 225 2003-01-01 00:00:00.000 2007-12-31 00:00:00.00021 1 276 1999-01-01 00:00:00.000 2002-12-31 00:00:00.0001815 1 599 1999-01-01 00:00:00.000 2004-12-31 00:00:00.0004479 1 599 2007-01-01 00:00:00.000 2009-12-31 00:00:00.0001084 16 6588 1996-10-01 00:00:00.000 2006-09-30 00:00:00.0004584 16 6588 2007-10-01 00:00:00.000 2008-09-30 00:00:00.0001100 21 167 1996-10-01 00:00:00.000 1999-12-31 00:00:00.0001103 21 270 1996-10-01 00:00:00.000 2009-12-31 00:00:00.0001415 30 4123 1996-10-01 00:00:00.000 2005-01-01 00:00:00.000 |
|
|
|
|
|