根据 sql 服务器 2012 中后续行索引之间的差异创建分区
create partition based on the difference between subsequent row indices in sql server 2012
我正在使用 SQL Server 2012。
我想根据后续行中的索引是否增加 1 或更多来创建一个 row_number。例如,假设我有一个 table 看起来像:
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' )
试试这个:
;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 开始可用)。
- 接下来计算CTE
当差异超过 1 并分配之后的所有记录
指向一个'group',直到找到下一个差异<> 1。这是
分组的关键步骤。
- 最后一步是使用
dense_rank
上一步计算得到行号的指标
根据需要。
此解决方案确实有一个 限制,因为如果差异不是按递增顺序排列,即如果示例数据中有两个以上的值(例如 52 和 53),它将失败, 它会将它们分类到第 3 组而不是创建一个新组。
更新:以下方法可以克服上述限制:
;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 步中,我们只检查过渡到不同值的连续值之间的差异,而不是使用 min/max 函数。然后排名使用条件总和为原始数据中的每个值分配一个组。
这可以进一步简化为:
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
对于大量记录,它可能表现不佳,但请尝试一下:
;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
我正在使用 SQL Server 2012。
我想根据后续行中的索引是否增加 1 或更多来创建一个 row_number。例如,假设我有一个 table 看起来像:
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' )
试试这个:
;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 开始可用)。 - 接下来计算CTE 当差异超过 1 并分配之后的所有记录 指向一个'group',直到找到下一个差异<> 1。这是 分组的关键步骤。
- 最后一步是使用
dense_rank
上一步计算得到行号的指标 根据需要。
此解决方案确实有一个 限制,因为如果差异不是按递增顺序排列,即如果示例数据中有两个以上的值(例如 52 和 53),它将失败, 它会将它们分类到第 3 组而不是创建一个新组。
更新:以下方法可以克服上述限制:
;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 步中,我们只检查过渡到不同值的连续值之间的差异,而不是使用 min/max 函数。然后排名使用条件总和为原始数据中的每个值分配一个组。
这可以进一步简化为:
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
对于大量记录,它可能表现不佳,但请尝试一下:
;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