将数字间隔分成组

Ron*_*tro 2 sql sql-server intervals dense-rank gaps-and-islands

我有下面的数字序列,每次下一个数字与前一个值相差一个以上单位时,我想制作一组新数字,即打破连续间隔

药片

value
1 
2
3
5
6
7
15
16
17
18
Run Code Online (Sandbox Code Playgroud)

由连续区间组成的组:

min max
1   3
5   7
15  18
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用dense_rank() 函数对行进行编号,如下例所示,然后我将能够按rankNumber 进行分组并获得MIN(value) 和MAX(value),但我没有找到要使用的模式此函数的 PARTITION BY 子句

value rankNumber
1     1
2     1
3     1
5     2
6     2
7     2
15    3
16    3
17    3
18    3

    WITH T2 AS
    (
     SELECT value, LEAD(value) OVER(ORDER BY value) as nextValue
     FROM T 
    )

    SELECT value, DENSE_RANK() 
     OVER(PARTITION BY CASE WHEN nextValue - value > 1 THEN 1 ELSE 0 END ORDER BY value)
    FROM T2
Run Code Online (Sandbox Code Playgroud)

创建表的代码:

CREATE TABLE t(
    value   INT
);
INSERT INTO t VALUES
    (1), (2), (3), (5), (6), (7), (15), (16), (17), (18);
Run Code Online (Sandbox Code Playgroud)

使用上述查询的当前输出:

value rankNumber
1     1
2     2
3     1
5     3
6     4
7     2
15    5
16    6
17    7
18    8
Run Code Online (Sandbox Code Playgroud)

Kin*_*ing 5

您需要想办法将序列转换为相应的组。我刚刚从这里的另一个用户那里学到了这个技巧。通过使用ROW_NUMBER遍历所有记录的 ,您可以通过value从该行号中减去同一记录上的来计算组键。如果values是连续的,则减法结果不会发生变化(因此产生相同的组密钥)。否则,组键将跳转到下一个(较小的)值。每次跳跃,组键都会变小。

这是查询:

select min(value) min, max(value) max
from (select value, ROW_NUMBER() over (order by value) - value as [key] 
      from t) v
group by [key]
order by min
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的答案!:) (2认同)