Mik*_*ion 8 sql-server sql-server-2008 gaps-and-islands
我有一个表格,其中包含以下定义
CREATE TABLE mytable
(
id INT IDENTITY(1, 1) PRIMARY KEY,
number BIGINT,
status INT
)
Run Code Online (Sandbox Code Playgroud)
和示例数据
INSERT INTO mytable
VALUES (100,0),
(101,0),
(102,0),
(103,0),
(104,1),
(105,1),
(106,0),
(107,0),
(1014,0),
(1015,0),
(1016,1),
(1017,0)
Run Code Online (Sandbox Code Playgroud)
仅查看status = 0
如何将Number
值折叠为连续序列号范围并查找每个范围的开始和结束的行?
即对于示例数据,结果将是
FROM to
Number 100 103
Number 106 107
Number 1014 1015
Number 1017 1017
Run Code Online (Sandbox Code Playgroud)
Mar*_*ith 27
正如评论中所提到的,这是一个典型的差距和岛屿问题.
由Itzik Ben Gan推广的解决方案是使用ROW_NUMBER() OVER (ORDER BY number) - number
在"岛屿"内保持不变并且不能出现在多个岛屿中的事实.
WITH T
AS (SELECT ROW_NUMBER() OVER (ORDER BY number) - number AS Grp,
number
FROM mytable
WHERE status = 0)
SELECT MIN(number) AS [From],
MAX(number) AS [To]
FROM T
GROUP BY Grp
ORDER BY MIN(number)
Run Code Online (Sandbox Code Playgroud)
注意:如果number
不能保证是唯一的替换ROW_NUMBER
与DENSE_RANK
上面的代码.
归档时间: |
|
查看次数: |
4768 次 |
最近记录: |