2016-09-15 33 views
0

我使用SQL Server 2012的创建基于SQL Server的下一行指数之间的差值2012

我要创建基于是否在后续行指数由1个或多个增加ROW_NUMBER分区。例如,假设我有一个表,看起来像:

event row_index 
    1  24   
    2  25 
    3  26 
    4  30 
    5  31 
    6  42 
    7  43 
    8  44 
    9  45 

然后我想要做的就是创建在最后一列,被称为seq_ID:

event row_index seq_id 
    1  24   1   
    2  25   1 
    3  26   1 
    4  30   2 
    5  31   2 
    6  42   3 
    7  43   3 
    8  44   3 
    9  45   3 

基本上,seq_id唯一机会,如果随后排指标之间的差异> 1。我曾尝试使用:

rank() over (partition by 'not sure what to put here')

+0

SQL的哪个版本服务器? –

+0

@ shree.pat18更新 – dimebucker91

回答

1

试试这个:

;with cte as 
    (select *, 
    coalesce(row_index - (lag(row_index) over (order by event)),1) diff 
    from tbl 
    ), 

    cte2 as 
    (select *, 
    (select max(diff) 
     from cte c 
     where c.row_index <= d.row_index 
    ) minri 
    from cte d 
    ) 

    select event, row_index, minri, 
    dense_rank() over (order by minri) rn 
    from cte2 
  • 第一CTE得到使用lag功能 (可从SQL Server 2012年起)的差异。
  • 当差值超过1时,下一个CTE计算出 ,并将指定 之后的所有记录指向“组”,直到找到下一个差异<> 1。这是 分组的关键一步。
  • 最后一步是使用dense_rank而不是 在上一步中计算的指标,以根据需要获取行号 。

此解决方案并具有限制在它将如果差异是不按递增顺序即,如果你在诸如52和53的样品数据中的两个以上值失败,它将它们分为组3而不是创建一个新的组。

Demo

更新:下面的方法能够克服上述限制:

;with cte as 
    (select *, 
    coalesce(row_index - (lag(row_index) over (order by event)),1) diff 
    from tbl) 
    ,cte2 as 
    (select *, 
    diff - coalesce(diff - (lag(diff) over (order by event)),0) tmp 
    from cte d) 

    select event,row_index, 
    1 + sum(case when tmp >= diff then 0 else 1 end) over (order by event) risum 
    from cte2 

同样的第一步是相同的。但在步骤2中,我们只检查是否转换为连续值之间的差值的不同值,而不是使用最小/最大值函数。排名然后使用条件总和为原始数据中的每个值分配一个组。

Demo

这可以进一步简化为:

select event, row_index, 
sum(case when diff <= 1 then 0 else 1 end) over (order by event) as rb 
from 
(select *, 
row_index - (lag(row_index) over (order by event)) diff 
from tbl 
) s 
+0

如果我想在2008年实现这一点,唯一的办法是创建多个CTE加入他们在b.row_index = a.row_index - 1等 – dimebucker91

1

随着记录一个庞大的数字,可能表现不好,但不妨一试:

;with T as (
select event, rowindex, rowindex-row_number() over (order by event) as rn from YourTableName 
) 
select event, (select count(distinct rn)+1 from T where rn<TT.rn) as seq_id 
from T TT order by event