2016-09-15 46 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