Author |
Topic |
ckimus
Starting Member
4 Posts |
Posted - 2015-01-30 : 20:17:20
|
Hello, I wonder if anyone here can help me. I have a table that currently looks something like below. CLID VisID VisitStrt VisitEnd. Bldg RoomStart RoomStatus ----------------------------------------------------- 1011 10261 1/01/2015 1/07/2015 1555 1/01/2015 Occupied 1011 10261 1/01/2015 1/07/2015 1555 1/02/2015 Occupied 1011 10261 1/01/2015 1/07/2015 1555 1/03/2015 Occupied 1011 10261 1/01/2015 1/07/2015 1555 1/04/2015 Away 1011 10261 1/01/2015 1/07/2015 1555 1/05/2015 Occupied 1011 10261 1/01/2015 1/07/2015 1555 1/06/2015 Reserved 1011 10261 1/01/2015 1/07/2015 1555 1/07/2015 Occupied 1011 10265 1/15/2015 1/20/2015 1777 1/15/2015 Occupied 1011 10265 1/15/2015 1/20/2015 1777 1/16/2015 Occupied 1011 10265 1/15/2015 1/20/2015 1777 1/17/2015 Occupied 1011 10265 1/15/2015 1/20/2015 1777 1/18/2015 Away 1011 10265 1/15/2015 1/20/2015 1777 1/19/2015 Occupied 1011 10265 1/15/2015 1/20/2015 1777 1/20/2015 OccupiedI have been trying to group this so that each Status has one RoomStart and one RoomEnd, getting rid rows in between. The result would look like this:CLID VisID VisitStrt VisitEnd. Bldg RoomStart RoomEnd RoomStatus-----------------------------------------------------------------1011 10261 1/01/2015 1/07/2015 1555 1/01/2015 1/03/2015 Occupied1011 10261 1/01/2015 1/07/2015 1555 1/04/2015 1/04/2015 Away1011 10261 1/01/2015 1/07/2015 1555 1/05/2015 1/05/2015 Occupied1011 10261 1/01/2015 1/07/2015 1555 1/06/2015 1/06/2015 Reserved1011 10261 1/01/2015 1/07/2015 1555 1/07/2015 1/07/2015 Occupied1011 10265 1/15/2015 1/20/2015 1777 1/15/2015 1/17/2015 Occupied1011 10265 1/15/2015 1/20/2015 1777 1/18/2015 1/18/2015 Away1011 10265 1/15/2015 1/20/2015 1777 1/19/2015 1/20/2015 OccupiedAny ideas? I've found a solution using partion and a running total but this table is huge and the query takes far too long to run.Thanks |
|
gbritton
Master Smack Fu Yak Hacker
2780 Posts |
Posted - 2015-01-31 : 07:45:07
|
Do you realize that your desired solution has overlapping dates? e.g. bldg/room 1555/1011 is both away and occupied on jan 5, and both occupied and reserved on the 6th. Is that what you want? Why? (doesn't make sense to me) |
|
|
ckimus
Starting Member
4 Posts |
Posted - 2015-01-31 : 12:10:41
|
Ahh, well spotted. I typed this out by hand and didn't realize. I have edited it so they don't overlap. |
|
|
Ifor
Aged Yak Warrior
700 Posts |
Posted - 2015-01-31 : 12:23:58
|
Try interval packing with the difference in order method:-- *** Test Data ***CREATE TABLE #t( CLID int NOT NULL ,VisID int NOT NULL ,RoomStart date NOT NULL ,RoomStatus varchar(20) NOT NULL);INSERT INTO #tVALUES (1011, 10261, '20150101', 'Occupied') ,(1011, 10261, '20150102', 'Occupied') ,(1011, 10261, '20150103', 'Occupied') ,(1011, 10261, '20150104', 'Away') ,(1011, 10261, '20150105', 'Occupied') ,(1011, 10261, '20150106', 'Reserved') ,(1011, 10261, '20150107', 'Occupied') ,(1011, 10265, '20150115', 'Occupied') ,(1011, 10265, '20150116', 'Occupied') ,(1011, 10265, '20150117', 'Occupied') ,(1011, 10265, '20150118', 'Away') ,(1011, 10265, '20150119', 'Occupied') ,(1011, 10265, '20150120', 'Occupied');-- *** End Test Data ***WITH GrpsAS( SELECT * ,ROW_NUMBER() OVER (PARTITION BY CLID, VisID ORDER BY RoomStart) - ROW_NUMBER() OVER (PARTITION BY CLID, VisID, RoomStatus ORDER BY RoomStart) AS Grp FROM #t),RangesAS( SELECT CLID, VisID, RoomStatus, Grp ,MIN(RoomStart) AS RoomStart ,MAX(RoomStart) AS RoomEnd FROM Grps GROUP BY CLID, VisID, RoomStatus, Grp)SELECT CLID, VisID, RoomStart, RoomEnd, RoomStatusFROM RangesORDER BY RoomStart; |
|
|
ckimus
Starting Member
4 Posts |
Posted - 2015-01-31 : 13:09:33
|
Thanks for the reply, that was a great place to start. However, I found that if there was a new visit a few days after the last one with the same status, it got grouped with that previous visit. If the next visit looked like this: (1011, 10265, '20150123', '20150127', '20150123', 'Occupied')(1011, 10265, '20150123', '20150127', '20150124', 'Occupied')(1011, 10265, '20150123', '20150127', '20150124', 'Occupied')(1011, 10265, '20150123', '20150127', '20150126', 'Occupied')(1011, 10265, '20150123', '20150127', '20150127', 'Occupied');I added the VisitStart and VisitEnd to the query and it seems to work perfectly now. Is there any reason why it shouldn't?WITH GrpsAS( SELECT * ,ROW_NUMBER() OVER (PARTITION BY CLID, VisID ORDER BY RoomStart) - ROW_NUMBER() OVER (PARTITION BY CLID, VisID, RoomStatus ORDER BY RoomStart) AS Grp FROM t),RangesAS( SELECT CLID, VisitStart, VisitEnd, VisID, RoomStatus, Grp ,MIN(RoomStart) AS RoomStart ,MAX(RoomStart) AS RoomEnd FROM Grps GROUP BY CLID, VisitStart, VisitEnd, VisID, RoomStatus, Grp)SELECT CLID, VisID, VisitStart, VisitEnd,RoomStart, RoomEnd, RoomStatusFROM RangesORDER BY RoomStart; |
|
|
ckimus
Starting Member
4 Posts |
Posted - 2015-01-31 : 18:05:11
|
Thanks Ifor, your solution did it. I just included the VisitStart and VisitEnd to the group and it Works perfectly |
|
|
|
|
|