我在一些似乎应该非常简单的事情上遇到了困难,但我现在已经太累了,不能再惹它了所以我只是把它扔到这里,看看是否有人可以展示如何解决这个问题。 我试图做的是根据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等)。我相信必须有一个相对简单的解决方案,它不会涉及整个集合中的单个操作,但我无法弄清楚。 注意:编辑值def def to 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;
答案 0 :(得分:1)
如果我理解正确,您的查询将是
;WITH temp AS
(
select x.ID,
x.[Value],
pre.PreviousValue
from @X x
OUTER APPLY
(
SELECT TOP 1
x2.[Value] AS PreviousValue
FROM @X x2
WHERE x2.ID < x.ID
ORDER BY x2.ID DESC
) pre
),
temp1 AS
(
SELECT x2.[Value], min(x2.ID) AS MinGrId
FROM @X x2
GROUP BY x2.[Value]
),
temp2 AS
(
select t.*,
SUM(CASE
WHEN t.PreviousValue != t.[Value] OR t.PreviousValue IS null THEN 1
ELSE 0
END) OVER(ORDER BY t.ID) AS [SO],
dense_rank() OVER(ORDER BY t1.MinGrId) AS [GO]
from temp t
INNER JOIN temp1 t1 ON t.[Value] = t1.[Value]
)
SELECT t.ID, t.[Value], t.[GO], t.SO,
dense_rank() OVER(PARTITION BY t.[GO] ORDER BY t.SO) AS GSO
FROM temp2 t
ORDER BY t.ID