你能帮我找到Active为真的序列中的第一个和最后一个id。所以从这个结果
id | Active
---------------
1 | false
2 | false
3 | true
4 | true
5 | false
6 | false
7 | false
8 | true
9 | true
10 | false
11 | false
12 | true
13 | true
14 | true
我需要所有连续序列(其中active为true),包含start和end id
startId | endId
------------------------
3 | 4
8 | 9
12 | 14
答案 0 :(得分:6)
您可以使用岛屿解决方案执行此操作:
DECLARE @t TABLE
(
id INT ,
Active VARCHAR(10)
)
INSERT INTO @t
VALUES ( 1, 'false' ),
( 2, 'false' ),
( 3, 'true' ),
( 4, 'true' ),
( 5, 'false' ),
( 6, 'false' ),
( 7, 'false' ),
( 8, 'true' ),
( 9, 'true' ),
( 10, 'false' ),
( 11, 'false' ),
( 12, 'true' ),
( 13, 'true' ),
( 14, 'true' );
WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( ORDER BY id )
- ROW_NUMBER() OVER ( PARTITION BY Active ORDER BY id ) rn
FROM @t
)
SELECT MIN(id) AS StartID ,
MAX(id) AS EndID
FROM cte
WHERE Active = 'true'
GROUP BY rn
背后的想法是你只需要为岛屿分配一些值。看看你在cte中获得了什么:
id Active rn
1 false 0
2 false 0
3 true 2
4 true 2
5 false 2
6 false 2
7 false 2
8 true 5
9 true 5
10 false 4
11 false 4
12 true 7
13 true 7
14 true 7
答案 1 :(得分:5)
这是典型的间隙和岛屿问题。使用ROW_NUMBER
标识具有相同Active
值的连续记录组:
SELECT MIN(id) AS startId, MAX(id) AS endId
FROM (
SELECT id, Active,
ROW_NUMBER() OVER (ORDER BY id) -
ROW_NUMBER() OVER (PARTITION BY Active ORDER BY id) AS grp
FROM mytable) AS t
WHERE Active = 'true'
GROUP BY grp
外部查询只会根据Active = false
计算字段过滤掉grp
条记录和分组,以便获得startId
和endId
。