22,210
社区成员
发帖
与我相关
我的任务
分享
create table #test
(id int identity(1,1),ids nvarchar(3),status int )
insert into #test
select 'A0',1
union all
select 'A1',1
union all
select 'A2',0
union all
select 'A3',1
union all
select 'A4',0
union all
select 'A5',1
union all
select 'A6',1
union all
select 'A7',1
union all
select 'A8',1
union all
select 'A9',0
declare @t table (id int ,ids nvarchar(3),status int ,cnt int,grp int)
insert into @t(id,ids,status)
select * from test
declare @cnt int,@grp int
set @cnt=0
set @grp=1
update s
set @cnt=case when status=(select status from @t where id=s.id+1) then @cnt+1
else case when status=1 then @cnt+1 else 0 end end,
cnt=@cnt,
@grp=case when status=(select status from @t where id=s.id+1) or status=(select status from @t where id=s.id-1)
then @grp else @grp+1 end ,
grp=@grp
from @t s
select distinct t.id,t.ids,t.status from @t s,@t t where s.grp=t.grp and s.cnt>6 and t.status=1
declare @n int
set @n=1 --这里指定@n值
--set @n=2
--set @n=3
--set @n=4
--set @n=5
--找出最大连续数
declare @n1 int
select @n1=max(n)
from
(
select n=count(1)
from
(
select maxid=(select max(id) from #test b where not exists(select 1 from #test where id between a.id and b.id and status<>1))
from #test a
where status=1
) t
group by maxid
) tt
--设定实际连续数
set @n=case when @n>@n1 then @n1 else @n end
--选择结果
select top(@n) ids,status
from #test
where status=1
and id>=(select min(id) from #test t where not exists(select 1 from #test where id between t.id and t.id+@n-1 and status<>1))
order by id
--@n=1
/*
ids status
---- -----------
A0 1
(1 行受影响)
*/
--@n=2
/*
ids status
---- -----------
A0 1
A1 1
(2 行受影响)
*/
--@n=3
/*
ids status
---- -----------
A5 1
A6 1
A7 1
(3 行受影响)
*/
--@n=4
/*
ids status
---- -----------
A5 1
A6 1
A7 1
A8 1
(4 行受影响)
*/
--@n=5
/*
ids status
---- -----------
A5 1
A6 1
A7 1
A8 1
(4 行受影响)
*/
-------------------------------------------
-- Author : liangCK 小梁 & angellan 兰儿
-- Comment: 小梁 爱 兰儿
-- Date : 2009-05-29 17:35:40
-------------------------------------------
--> 生成测试数据: T
CREATE TABLE T(id INT,ids VARCHAR(3),status INT)
INSERT INTO T
SELECT 1,'A0',1 UNION ALL
SELECT 2,'A1',1 UNION ALL
SELECT 3,'A2',0 UNION ALL
SELECT 4,'A3',1 UNION ALL
SELECT 5,'A4',0 UNION ALL
SELECT 6,'A5',1 UNION ALL
SELECT 7,'A6',1 UNION ALL
SELECT 8,'A7',1 UNION ALL
SELECT 9,'A8',1 UNION ALL
SELECT 10,'A9',0 UNION ALL
SELECT 11,'A10',0
--SQL查询如下:
GO
CREATE PROC p @n INT
AS
;WITH LiangAndLan AS
(
SELECT TOP(1)
id,ids,status,class=1,rows=1
FROM T
WHERE status = 1
ORDER BY id
UNION ALL
SELECT
B.id,B.ids,B.status,
CASE WHEN A.status=B.status THEN A.class ELSE A.class+1 END,
CASE WHEN A.status=B.status THEN A.rows+1 ELSE 1 END
FROM LiangAndLan AS A
JOIN T AS B
ON A.id=B.id-1
--WHERE CASE WHEN A.status=B.status THEN A.rows+1 ELSE 1 END > @n
)
SELECT A.id,A.ids,A.status
FROM LiangAndLan AS A
JOIN (
SELECT TOP(1) * FROM LiangAndLan
WHERE rows <= @n AND status = 1 ORDER BY rows DESC,class
) AS B
ON A.class=B.class AND A.rows < = B.rows;
GO
EXEC p 1;
EXEC p 2;
EXEC p 3;
EXEC p 4;
EXEC p 6;
GO
DROP PROC p
DROP TABLE T
/*
id ids status
----------- ---- -----------
1 A0 1
(1 row(s) affected)
id ids status
----------- ---- -----------
1 A0 1
2 A1 1
(2 row(s) affected)
id ids status
----------- ---- -----------
6 A5 1
7 A6 1
8 A7 1
(3 row(s) affected)
id ids status
----------- ---- -----------
6 A5 1
7 A6 1
8 A7 1
9 A8 1
(4 row(s) affected)
id ids status
----------- ---- -----------
6 A5 1
7 A6 1
8 A7 1
9 A8 1
(4 row(s) affected)
*/
-------------------------------------------
-- Author : liangCK 小梁 & angellan 兰儿
-- Comment: 小梁 爱 兰儿
-- Date : 2009-05-29 17:35:40
-------------------------------------------
--> 生成测试数据: @T
DECLARE @T TABLE (id INT,ids VARCHAR(3),status INT)
INSERT INTO @T
SELECT 1,'A0',1 UNION ALL
SELECT 2,'A1',1 UNION ALL
SELECT 3,'A2',0 UNION ALL
SELECT 4,'A3',1 UNION ALL
SELECT 5,'A4',0 UNION ALL
SELECT 6,'A5',1 UNION ALL
SELECT 7,'A6',1 UNION ALL
SELECT 8,'A7',1 UNION ALL
SELECT 9,'A8',1 UNION ALL
SELECT 10,'A9',0 UNION ALL
SELECT 11,'A10',0
--SQL查询如下:
DECLARE @n INT;
SET @n = 6;
WITH LiangAndLan AS
(
SELECT TOP(1)
id,ids,status,class=1,rows=1
FROM @T
WHERE status = 1
ORDER BY id
UNION ALL
SELECT
B.id,B.ids,B.status,
CASE WHEN A.status=B.status THEN A.class ELSE A.class+1 END,
CASE WHEN A.status=B.status THEN A.rows+1 ELSE 1 END
FROM LiangAndLan AS A
JOIN @T AS B
ON A.id=B.id-1
--WHERE CASE WHEN A.status=B.status THEN A.rows+1 ELSE 1 END > @n
)
SELECT A.id,A.ids,A.status
FROM LiangAndLan AS A
JOIN (
SELECT TOP(1) * FROM LiangAndLan
WHERE rows <= @n AND status = 1 ORDER BY rows DESC,class
) AS B
ON A.class=B.class AND A.rows < = B.rows;
create table #test
(id int identity(1,1),ids nvarchar(3),status int )
insert into #test
select 'A0',1
union all
select 'A1',1
union all
select 'A2',0
union all
select 'A3',1
union all
select 'A4',0
union all
select 'A5',1
union all
select 'A6',1
union all
select 'A7',1
union all
select 'A8',1
union all
select 'A9',0
-->Start
select * into #1 from #test t where status=1 and not exists(select 1 from #test where status=1 and id=t.id-1)
select * into #2 from #test t where status=1 and not exists(select 1 from #test where status=1 and id=t.id+1)
select a.id as aid,b.id as bid
into #3
from
(select *,px=(select count(1)+1 from #1 where id<t.id) from #1 t) a,
(select *,px=(select count(1)+1 from #2 where id<t.id) from #2 t) b
where
a.px=b.px
select *
into #4
from #test a,#3 b,(select max(bid-aid) as maxid from #3) c
where
a.id between b.aid and b.bid
-->查询
declare @n int
set @n = 2 --可以根据需要修改
select
id,ids,status
from #4 t
where
bid-aid>=case when @n>=maxid then maxid else case when @n between aid and bid then bid-aid end end
and
(select count(1) from #4 where bid-aid>=@n and id<=t.id)<=@n
drop table #test,#1,#2,#3,#4
/**
id ids status
----------- ---- -----------
1 A0 1
2 A1 1
(所影响的行数为 2 行)
**/
--当@n = 1,取第一个status为1的(A0)
--当@n = 2,取第一,二个status为1的(A0,A1)
--当@n = 3,(A5,A6,A7)
--当@n = 4,(A5,A6,A7,A8)
--当@n>4时,(A5,A6,A7,A8)
create table #test
(id int identity(1,1),ids nvarchar(3),status int )
insert into #test
select 'A0',1
union all
select 'A1',1
union all
select 'A2',0
union all
select 'A3',1
union all
select 'A4',0
union all
select 'A5',1
union all
select 'A6',1
union all
select 'A7',1
union all
select 'A8',1
union all
select 'A9',0
declare @n int
set @n = 5
;with cte as
(
select type = 1,* from #test where id = (select min(id) from #test)
union all
select type = case when a.status = b.status then b.type else b.type+1 end,a.* from #test a ,cte b where a.id = b.id+1
)
,cte1 as
(
select *,px = row_number() over(partition by type order by id) from cte
)
select top(@n) id,ids,status from cte1 a
where exists(select 1 from cte1 where a.type = type and px >=case when @n > (select max(px) from cte1) then (select max(px) from cte1) else @n end)
and px <=@n and status = 1
order by id
drop table #test
/*
1 A0 1
2 A1 1
6 A5 1
7 A6 1
*/