Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
xalpha
Starting Member
13 Posts |
Posted - 2012-06-01 : 06:00:18
|
Hello,I have a very special query and hope someone has a good hint for me. I have the following fixes input data:ID Time Flag1 14:00:00 12 14:00:05 03 14:00:08 04 14:00:10 15 14:00:15 06 14:00:18 17 14:00:20 18 14:00:22 19 14:00:25 0The Output should be alternating like this:ID Time Flag1 14:00:00 13 14:00:08 04 14:00:10 15 14:00:15 08 14:00:22 19 14:00:25 0Has someone a good idea? I can't believe that it isn't possible without a stored procedure?Thank you for any idea. |
|
SQL Padawan
Starting Member
4 Posts |
Posted - 2012-06-01 : 11:23:52
|
I'm sure this can be done with a recursive CTE but here is a set-based solution:DECLARE @sampledata TABLE(id INT,time TIME,flag BIT)INSERT @sampledataSELECT 1,'14:00:00',1UNION ALLSELECT 2,'14:00:05',0UNION ALLSELECT 3,'14:00:08',0UNION ALLSELECT 4,'14:00:10',1UNION ALLSELECT 5,'14:00:15',0UNION ALLSELECT 6,'14:00:18',1UNION ALLSELECT 7,'14:00:20',1UNION ALLSELECT 8,'14:00:22',1UNION ALLSELECT 9,'14:00:25',0SELECT s1.id,s1.time,s1.flagFROM @sampledata s1 LEFT JOIN @sampledata s2 ON s1.id < s2.id AND s1.flag = s2.flag AND NOT EXISTS( SELECT 1 FROM @sampledata s3 WHERE s3.flag != s1.flag AND s3.id BETWEEN s1.id AND s2.id )WHERE s2.id IS NULLORDER BY s1.id |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-01 : 11:49:45
|
[code]SELECT t.ID,t.[Time],t.FlagFROM(SELECT ROW_NUMBER() OVER (PARTITION BY PrevTime ORDER BY [Time] DESC) AS Rn,t.*FROM Table tOUTER APPLY (SELECT MAX([Time]) AS PrevTime FROM table WHERE ID < t.ID AND Flag <> t.Flag )t1)rWHERE Rn=1[/code]------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-01 : 11:52:48
|
quote: Originally posted by SQL Padawan I'm sure this can be done with a recursive CTE but here is a set-based solution:DECLARE @sampledata TABLE(id INT,time TIME,flag BIT)INSERT @sampledataSELECT 1,'14:00:00',1UNION ALLSELECT 2,'14:00:05',0UNION ALLSELECT 3,'14:00:08',0UNION ALLSELECT 4,'14:00:10',1UNION ALLSELECT 5,'14:00:15',0UNION ALLSELECT 6,'14:00:18',1UNION ALLSELECT 7,'14:00:20',1UNION ALLSELECT 8,'14:00:22',1UNION ALLSELECT 9,'14:00:25',0SELECT s1.id,s1.time,s1.flagFROM @sampledata s1 LEFT JOIN @sampledata s2 ON s1.id < s2.id AND s1.flag = s2.flag AND NOT EXISTS( SELECT 1 FROM @sampledata s3 WHERE s3.flag != s1.flag AND s3.id BETWEEN s1.id AND s2.id )WHERE s2.id IS NULLORDER BY s1.id
It involves a hidden RBAR which can hurt performancesee this nice article by Jeffhttp://www.sqlservercentral.com/articles/T-SQL/61539/------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2012-06-01 : 12:17:00
|
I was goofing around, and realized I did a 2012 solution. Although, it doesn't help the OP; I'm posting it just incase it helps anyone else (assuming it actually works correctly):SELECT *FROM ( SELECT *, LEAD(flag, 1, NULL) OVER (ORDER BY id) AS NextFlag FROM @sampledata ) AS AWHERE flag <> NextFlag OR NextFlag IS NULL |
 |
|
SQL Padawan
Starting Member
4 Posts |
Posted - 2012-06-01 : 12:23:46
|
quote: Originally posted by visakh16
quote: Originally posted by SQL Padawan I'm sure this can be done with a recursive CTE but here is a set-based solution:DECLARE @sampledata TABLE(id INT,time TIME,flag BIT)INSERT @sampledataSELECT 1,'14:00:00',1UNION ALLSELECT 2,'14:00:05',0UNION ALLSELECT 3,'14:00:08',0UNION ALLSELECT 4,'14:00:10',1UNION ALLSELECT 5,'14:00:15',0UNION ALLSELECT 6,'14:00:18',1UNION ALLSELECT 7,'14:00:20',1UNION ALLSELECT 8,'14:00:22',1UNION ALLSELECT 9,'14:00:25',0SELECT s1.id,s1.time,s1.flagFROM @sampledata s1 LEFT JOIN @sampledata s2 ON s1.id < s2.id AND s1.flag = s2.flag AND NOT EXISTS( SELECT 1 FROM @sampledata s3 WHERE s3.flag != s1.flag AND s3.id BETWEEN s1.id AND s2.id )WHERE s2.id IS NULLORDER BY s1.id
It involves a hidden RBAR which can hurt performancesee this nice article by Jeffhttp://www.sqlservercentral.com/articles/T-SQL/61539/------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/
He could use this one then SELECT s1.id,s1.time,s1.flagFROM @sampledata s1LEFT JOIN @sampledata s2 ON s1.id = s2.id - 1 AND s1.flag = s2.flagWHERE s2.id IS NULLThis builds on Lamprey's post. (thanks! ) |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-01 : 12:28:17
|
quote: Originally posted by SQL Padawan
quote: Originally posted by visakh16
quote: Originally posted by SQL Padawan I'm sure this can be done with a recursive CTE but here is a set-based solution:DECLARE @sampledata TABLE(id INT,time TIME,flag BIT)INSERT @sampledataSELECT 1,'14:00:00',1UNION ALLSELECT 2,'14:00:05',0UNION ALLSELECT 3,'14:00:08',0UNION ALLSELECT 4,'14:00:10',1UNION ALLSELECT 5,'14:00:15',0UNION ALLSELECT 6,'14:00:18',1UNION ALLSELECT 7,'14:00:20',1UNION ALLSELECT 8,'14:00:22',1UNION ALLSELECT 9,'14:00:25',0SELECT s1.id,s1.time,s1.flagFROM @sampledata s1 LEFT JOIN @sampledata s2 ON s1.id < s2.id AND s1.flag = s2.flag AND NOT EXISTS( SELECT 1 FROM @sampledata s3 WHERE s3.flag != s1.flag AND s3.id BETWEEN s1.id AND s2.id )WHERE s2.id IS NULLORDER BY s1.id
It involves a hidden RBAR which can hurt performancesee this nice article by Jeffhttp://www.sqlservercentral.com/articles/T-SQL/61539/------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/
He could use this one then SELECT s1.id,s1.time,s1.flagFROM @sampledata s1LEFT JOIN @sampledata s2 ON s1.id = s2.id - 1 AND s1.flag = s2.flagWHERE s2.id IS NULLThis builds on Lamprey's post. (thanks! )
yep looks fine and works so far as ID values doesnt have gaps------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-01 : 12:29:12
|
quote: Originally posted by Lamprey I was goofing around, and realized I did a 2012 solution. Although, it doesn't help the OP; I'm posting it just incase it helps anyone else (assuming it actually works correctly):SELECT *FROM ( SELECT *, LEAD(flag, 1, NULL) OVER (ORDER BY id) AS NextFlag FROM @sampledata ) AS AWHERE flag <> NextFlag OR NextFlag IS NULL
yep...good example of LEAD functionthanks for sharing ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
xalpha
Starting Member
13 Posts |
Posted - 2012-06-06 : 10:46:40
|
Thank you community! I have learned a lot with this topic. This are really genius queries - Thank you very much! I'm looking forward to test 2012 with the new functions. The example with LEAD ist very interesting. As far as I have to use 2008 the other examples are perfect work! Great...Matthias |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-07 : 23:03:54
|
welcomeGlad that we could contribute something to enhance your knowledge------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
|
|
|
|