0

我有桌子@NumberRange。它有一个开始和结束编号。我必须找出范围是按顺序排列的

Declare @NumberRange table
(
    Id int primary key, 
    ItemId int,
    [start] int,
    [end] int
)


INSERT INTO @NumberRange
VALUES  
(1,1,1,10),
(2,1,11,20),
(3,1,21,30),
(4,1,40,50),
(5,1,51,60),
(6,1,61,70),
(7,1,80,90),
(8,1,100,200) 

预期结果:

在此处输入图像描述

注意:如果任何连续数字(即 1 到 10 ,11-20,21-30 是连续数字)计算结果列。所以结果列更新为 1,然后 41-50 不是连续的数字(因为前一行以 30 结束,下一行从 40 开始),这就是为什么结果列将是 2 并且它是连续的。

在第 4 次以 50 结束,第 5 次以 51 连续开始,那么结果将是 3,因为我已经区分结果 1...

我使用了lead函数,但没有得到预期的结果,..请有人帮我得到结果吗?

解决方法:

select  
    *,
    [Diff] = [Lead] - [end], 
    [Result] = Rank() OVER (PARTITION BY ([Lead] - [end]) ORDER BY Id) 
from 
    (select 
         id, [start], [end], LEAD([start]) over (order by id) as [Lead] 
     from 
         @NumberRange) Z   
order by 
    id
4

2 回答 2

2

用于lag()确定组的开始位置。然后是枚举它们的累积总和:

select nr.*,
       sum(case when startr = prev_endr + 1  then 0 else 1 end) over (partition by itemid order by startr) as grp
from (select nr.*, lag(endr) over (partition by itemid order by startr) as prev_endr
      from numberrange nr
     ) nr;

是一个 db<>fiddle。

这个答案假设 ids 4 和 5 是连续的,这基于问题的其余部分是有意义的。

于 2019-03-29T11:22:20.173 回答
1

您的预期结果尚不清楚,我也有评论中提出的问题,但我认为您想要做的类似于

select  N1.*,case when N1.[end]+1=N2.[start] then 1 else 2 end Result from @NumberRange N1 inner join @NumberRange N2 on N1.Id=N2.Id-1 

在此处输入图像描述

于 2019-03-29T11:18:55.837 回答