我想我会发布我制定的另一种方法,我认为更多的是类似于其他人正在考虑的 dense_rank() 工作。唯一的假设是 _order 是一个连续的整数(即没有间隙)。
与之前相同的数据设置:
if object_id('tempdb.dbo.#t') is not null drop table #t
create table #t
(
_order int primary key clustered,
_type int,
_grp int
)
insert into #t (_order, _type)
select 1,7
union all select 2,11
union all select 3,11
union all select 4,18
union all select 5,5
union all select 6,19
union all select 7,5
union all select 8,5
union all select 9,3
union all select 10,11
union all select 11,11
union all select 12,3
这种方法的作用是row_number 每个_type,因此无论_type 存在于何处,以及出现多少次,这些类型都将具有一个按_order 字段顺序唯一的row_number。通过从全局行号(即_order)中减去特定类型的行号,您将得到组。这是此代码的代码,然后我也将逐步介绍。
;with tr as
(
select
-- Create an incrementing integer row_number over each _type (regardless of it's position in the sequence)
_type_rid = row_number() over (partition by _type order by _order),
-- This shows that on rows 6-8 (the transition between type 19 and 5), naively they're all assigned the same group
naive_type_rid = _order - row_number() over (partition by _type order by _order),
-- By adding a value to the type_rid which is a function of _type, those two values are distinct.
-- Originally I just added the value, but I think squaring it ensures that there can't ever be another gap of 1
true_type_rid = (_order - row_number() over (partition by _type order by _order)) + power(_type, 2),
_type,
_order
from #t
-- order by _order -- uncomment this if you want to run the inner select separately
)
select
_grp = dense_rank() over (order by max(_order)),
_type = max(_type)
from tr
group by true_type_rid
order by max(_order)
发生了什么
首先要做的事;我不必在src cte 中创建单独的列来返回_type_rid。我这样做主要是为了排除故障和澄清问题。其次,我也不必再为_grp 列的最终选择做第二次dense_rank。我只是这样做了,所以它与我的其他方法的结果完全匹配。
在每种类型中,type_rid 是唯一的,并且递增 1。_order 也递增 1。因此,只要给定的类型正在运行,仅间隔 1,_order - _type_rid 将是相同的值。让我们看几个例子(这是src cte 的结果,由_order 排序):
_type_rid naive_type_rid true_type_rid _type _order
-------------------- -------------------- -------------------- ----------- -----------
1 8 17 3 9
2 10 19 3 12
1 4 29 5 5
2 5 30 5 7
3 5 30 5 8
1 0 49 7 1
1 1 122 11 2
2 1 122 11 3
3 7 128 11 10
4 7 128 11 11
1 3 327 18 4
1 5 366 19 6
第一行,_order - _type_rid = 1 - 1 = 0。这会将这一行(类型 7)分配给组 0
第二行,2 - 1 = 1。这将类型 11 分配给组 1
第三行,3 - 2 = 1。这也将第二个顺序类型 11 分配给组 1
第四行,4 - 1 = 3。这将类型 18 分配给组 3
...等等。
这些组不是连续的,但它们的顺序与_order 相同,这是重要的部分。您还会注意到我还将_type 的值添加到该值中。那是因为当我们点击后面的一些行时,组切换了,但序列仍然递增 1。通过添加 _type,我们可以区分这些非一值,并且仍然以正确的顺序执行。
src 的最终外部选择按 max(_order) 排序(在我不必要的 dense_rank() _grp 修改中,以及只是一般结果顺序)。
结论
这仍然有点不稳定,但绝对在“支持的功能”范围内。鉴于我在那里遇到了一个问题(一件一件的事情),可能还有其他我没有考虑过的问题,所以再一次,用一粒盐,做一些测试。