I have some data. I want to group them based on the value of data
column. If there are 3 or more consecutive rows that have data bigger than 10, then those rows are what I want.
So for this data:
use tempdb;
go
set nocount on;
if object_id('t', 'U') is not null
drop table t;
go
create table t
(
id int primary key identity,
[when] datetime,
data int
)
go
insert into t([when], data) values ('20130801', 1);
insert into t([when], data) values ('20130802', 121);
insert into t([when], data) values ('20130803', 132);
insert into t([when], data) values ('20130804', 15);
insert into t([when], data) values ('20130805', 9);
insert into t([when], data) values ('20130806', 1435);
insert into t([when], data) values ('20130807', 143);
insert into t([when], data) values ('20130808', 18);
insert into t([when], data) values ('20130809', 19);
insert into t([when], data) values ('20130810', 1);
insert into t([when], data) values ('20130811', 1234);
insert into t([when], data) values ('20130812', 124);
insert into t([when], data) values ('20130813', 6);
select * from t;
What I want is:
id when data
----------- ----------------------- -----------
2 2013-08-02 00:00:00.000 121
3 2013-08-03 00:00:00.000 132
4 2013-08-04 00:00:00.000 15
6 2013-08-06 00:00:00.000 1435
7 2013-08-07 00:00:00.000 143
8 2013-08-08 00:00:00.000 18
9 2013-08-09 00:00:00.000 19
How to do that?
Try this
SQL FIDDLE DEMO
OUTPUT
EDIT
First the inner query counts the no of records where data <= 10
output
Then we filter the records with data > 10
Now we count the records by partitoning cnt column
Output
The above query is put in cte just like temp table
Now select the records that are having the consecutive count >= 3
ANOTHER SOLUTION
Reference URL
SQL FIDDLE DEMO
First, we discount any row that has a value of 10 or less:
Next, get the rows whose immediate predecessor is also more than 10:
Also get the rows whose immediate successor is also more than 10:
Finally, select any row where it either starts a sequence of 3, is in the middle of one, or ends one:
A row whose valid right side also has a valid right side starts a sequence of at least 3:
A row whose predecessor and successor are both valid is in the middle of at least 3:
A row whose valid left side also has a valid left side ends a sequence of at least 3:
Join them all up, with UNION to remove duplicates:
SQL Fiddler: http://sqlfiddle.com/#!3/12f3a/9
Edit: I like BVR's answer, much more elegant than mine.