I am stymied on something that seems like it should be really simple but I am too tired to mess with it anymore right now so I am just throwing this out here to see if anyone can show how to go about this. What I am attempting to do is identify the rows of a table according to the group, the sequence, and the order of the sequence to which the values in the table belong as ordered by the IDENTITY column (ID). I am using 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;
The end result should look something like this:
/*
*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
*/
I hope that it is acceptable that I am going to spare you the variety of failed attempts (involving row_number, rank, dense_rank, group by, etc) which I have made thus far ...; I am sure there must be a relatively simple solution that doesn't involve much more than a single operation across the set but I can't figure it out. NOTE: Edited Value def to zzz to make the requested ordering more clear. I hope that makes sense and thanks in advance!
SOLUTION:
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;