SQL Server Forums
Profile | Register | Active Topics | Members | Search | Forum FAQ
 
Register Now and get your question answered!
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 Tricky query
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

xalpha
Starting Member

11 Posts

Posted - 06/01/2012 :  06:00:18  Show Profile  Reply with Quote
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 Flag
1 14:00:00 1
2 14:00:05 0
3 14:00:08 0
4 14:00:10 1
5 14:00:15 0
6 14:00:18 1
7 14:00:20 1
8 14:00:22 1
9 14:00:25 0

The Output should be alternating like this:

ID Time Flag
1 14:00:00 1
3 14:00:08 0
4 14:00:10 1
5 14:00:15 0
8 14:00:22 1
9 14:00:25 0

Has 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 - 06/01/2012 :  11:23:52  Show Profile  Reply with Quote
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 @sampledata
SELECT 1,'14:00:00',1
UNION ALL
SELECT 2,'14:00:05',0
UNION ALL
SELECT 3,'14:00:08',0
UNION ALL
SELECT 4,'14:00:10',1
UNION ALL
SELECT 5,'14:00:15',0
UNION ALL
SELECT 6,'14:00:18',1
UNION ALL
SELECT 7,'14:00:20',1
UNION ALL
SELECT 8,'14:00:22',1
UNION ALL
SELECT 9,'14:00:25',0

SELECT s1.id,s1.time,s1.flag
FROM @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 NULL
ORDER BY s1.id
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

India
47157 Posts

Posted - 06/01/2012 :  11:49:45  Show Profile  Reply with Quote

SELECT t.ID,
t.[Time],
t.Flag
FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY PrevTime ORDER BY [Time] DESC) AS Rn,t.*
FROM Table t
OUTER APPLY (SELECT MAX([Time]) AS PrevTime
             FROM table
             WHERE ID < t.ID
             AND Flag <> t.Flag
            )t1
)r
WHERE Rn=1


------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

India
47157 Posts

Posted - 06/01/2012 :  11:52:48  Show Profile  Reply with Quote
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 @sampledata
SELECT 1,'14:00:00',1
UNION ALL
SELECT 2,'14:00:05',0
UNION ALL
SELECT 3,'14:00:08',0
UNION ALL
SELECT 4,'14:00:10',1
UNION ALL
SELECT 5,'14:00:15',0
UNION ALL
SELECT 6,'14:00:18',1
UNION ALL
SELECT 7,'14:00:20',1
UNION ALL
SELECT 8,'14:00:22',1
UNION ALL
SELECT 9,'14:00:25',0

SELECT s1.id,s1.time,s1.flag
FROM @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 NULL
ORDER BY s1.id



It involves a hidden RBAR which can hurt performance

see this nice article by Jeff

http://www.sqlservercentral.com/articles/T-SQL/61539/

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

Lamprey
Flowing Fount of Yak Knowledge

3832 Posts

Posted - 06/01/2012 :  12:17:00  Show Profile  Reply with Quote
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 A
WHERE
	flag <> NextFlag
	OR NextFlag IS NULL
Go to Top of Page

SQL Padawan
Starting Member

4 Posts

Posted - 06/01/2012 :  12:23:46  Show Profile  Reply with Quote
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 @sampledata
SELECT 1,'14:00:00',1
UNION ALL
SELECT 2,'14:00:05',0
UNION ALL
SELECT 3,'14:00:08',0
UNION ALL
SELECT 4,'14:00:10',1
UNION ALL
SELECT 5,'14:00:15',0
UNION ALL
SELECT 6,'14:00:18',1
UNION ALL
SELECT 7,'14:00:20',1
UNION ALL
SELECT 8,'14:00:22',1
UNION ALL
SELECT 9,'14:00:25',0

SELECT s1.id,s1.time,s1.flag
FROM @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 NULL
ORDER BY s1.id



It involves a hidden RBAR which can hurt performance

see this nice article by Jeff

http://www.sqlservercentral.com/articles/T-SQL/61539/

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/





He could use this one then

SELECT s1.id,s1.time,s1.flag
FROM @sampledata s1
LEFT JOIN @sampledata s2 ON s1.id = s2.id - 1 AND s1.flag = s2.flag
WHERE s2.id IS NULL

This builds on Lamprey's post. (thanks! )
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

India
47157 Posts

Posted - 06/01/2012 :  12:28:17  Show Profile  Reply with Quote
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 @sampledata
SELECT 1,'14:00:00',1
UNION ALL
SELECT 2,'14:00:05',0
UNION ALL
SELECT 3,'14:00:08',0
UNION ALL
SELECT 4,'14:00:10',1
UNION ALL
SELECT 5,'14:00:15',0
UNION ALL
SELECT 6,'14:00:18',1
UNION ALL
SELECT 7,'14:00:20',1
UNION ALL
SELECT 8,'14:00:22',1
UNION ALL
SELECT 9,'14:00:25',0

SELECT s1.id,s1.time,s1.flag
FROM @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 NULL
ORDER BY s1.id



It involves a hidden RBAR which can hurt performance

see this nice article by Jeff

http://www.sqlservercentral.com/articles/T-SQL/61539/

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/





He could use this one then

SELECT s1.id,s1.time,s1.flag
FROM @sampledata s1
LEFT JOIN @sampledata s2 ON s1.id = s2.id - 1 AND s1.flag = s2.flag
WHERE s2.id IS NULL

This builds on Lamprey's post. (thanks! )


yep looks fine and works so far as ID values doesnt have gaps

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

India
47157 Posts

Posted - 06/01/2012 :  12:29:12  Show Profile  Reply with Quote
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 A
WHERE
	flag <> NextFlag
	OR NextFlag IS NULL



yep...good example of LEAD function
thanks for sharing

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

xalpha
Starting Member

11 Posts

Posted - 06/06/2012 :  10:46:40  Show Profile  Reply with Quote
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
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

India
47157 Posts

Posted - 06/07/2012 :  23:03:54  Show Profile  Reply with Quote
welcome
Glad that we could contribute something to enhance your knowledge

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
SQL Server Forums © 2000-2009 SQLTeam Publishing, LLC Go To Top Of Page
This page was generated in 0.09 seconds. Powered By: Snitz Forums 2000