【发布时间】:2017-08-01 03:55:06
【问题描述】:
我在一些看起来应该很简单的事情上遇到了困难,但我现在太累了,不能再搞砸了,所以我只是把它扔在这里,看看是否有人可以展示如何解决这个问题。 我正在尝试根据 IDENTITY 列 (ID) 排序的表中的值所属的组、序列和序列的顺序来识别表的行。 我正在使用 Microsoft SQL Server 2008 R2 Management Studio (v10.50.4000.0)。
declare @X table (
ID int identity,
Value varchar(20)
);
insert @X
select 'abc'
union all
select 'zzz' --def
union all
select 'abc'
union all
select 'abc'
union all
select 'xyz'
union all
select 'abc'
union all
select 'abc';
select * from @X;
最终结果应该是这样的:
/*
*GO-GroupOrder; SO-SequenceOrder; GSO-GroupSequenceOrder
ID Value GO SO GSO
1 abc 1 1 1
2 zzz 2 2 1 --def
3 abc 1 3 2
4 abc 1 3 2
5 xyz 3 4 1
6 abc 1 5 3
7 abc 1 5 3
*/
我希望我能避免我迄今为止所做的各种失败尝试(涉及 row_number、rank、dense_rank、group by 等)是可以接受的……;我确信必须有一个相对简单的解决方案,它只涉及整个集合中的单个操作,但我无法弄清楚。 注意:将值定义为 zzz 以使请求的顺序更清晰。 我希望这是有道理的,并提前感谢!
解决方案:
with
cte1 as (
select
x.ID,
x.Value,
oX.ValuePrevious
from @X as x
outer apply (
select
top 1
oX.Value as ValuePrevious
from @X as oX
where x.ID > oX.ID
order by oX.ID desc
) as oX
),
cte2 as (
select
min(ID) as IDMin,
Value
from @x
group by Value
),
cte3 as (
select
cte1.ID,
cte1.Value,
dense_rank() over (order by cte2.IDMin) as [GO],
cCTE1.SO
from cte1
cross apply (
select
sum(case
when 1 <> 1
or cCTE1.ValuePrevious != cCTE1.[Value]
or cCTE1.ValuePrevious is NULL
then 1
else 0
end) as SO
from cte1 as cCTE1
where cte1.ID >= cCTE1.ID
) as cCTE1
join cte2
on cte2.Value = cte1.Value
)
select
ID,
Value,
[GO],
SO,
dense_rank() over (partition by [GO] order by SO) as [GSO]
from cte3 order by ID;
【问题讨论】:
标签: sql-server sql-server-2008-r2