12

我有一个具有以下定义的表

CREATE TABLE mytable
  (
     id     INT IDENTITY(1, 1) PRIMARY KEY,
     number BIGINT,
     status INT
  )

和示例数据

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)

只看status = 0我如何折叠的行Number值折叠成连续序列号范围并找到每个范围的开始和结束的行?

即对于示例数据,结果将是

         FROM      to 
Number    100      103
Number    106      107
Number    1014     1015
Number    1017     1017
4

1 回答 1

33

正如评论中提到的,这是一个典型的差距和孤岛问题。

ROW_NUMBER() OVER (ORDER BY number) - numberItzik Ben Gan 推广的一个解决方案是使用在一个“岛屿”内保持不变并且不能出现在多个岛屿中的事实。

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) 

注意:如果number不保证在上面的代码中是唯一的ROW_NUMBER替换为。DENSE_RANK

于 2013-06-11T14:34:03.640 回答