0

次のクエリ、

declare @data as TABLE (one int, two int);
insert into @data (one, two) values (1,1)
insert into @data (one, two) values (2,1)
insert into @data (one, two) values (3,2)
insert into @data (one, two) values (4,2)
insert into @data (one, two) values (5,2)
insert into @data (one, two) values (6,1)
insert into @data (one, two) values (7,1)
insert into @data (one, two) values (8,3)
insert into @data (one, two) values (9,3)
select  one, two,
dense_rank() OVER (ORDER BY two ASC) AS BlockNumber --Same dates same number
from @data
order by one

結果とともに、

one two BlockNumber
1   1   1
2   1   1
3   2   2
4   2   2
5   2   2
6   1   1
7   1   1
8   3   3
9   3   3

ただし、次の結果が必要です。

one two BlockNumber
1   1   1
2   1   1
3   2   2
4   2   2
5   2   2
6   1   3**
7   1   3**
8   3   4**
9   3   4**

助言がありますか?

4

2 に答える 2

1
;WITH T1
     AS (SELECT one,
                two,
                dense_rank() OVER (ORDER BY one) - 
                dense_rank() OVER (PARTITION BY two ORDER BY one) AS Grp
         FROM   @data),
     T2
     AS (SELECT *,
                MIN(one) OVER (PARTITION BY Grp) AS MinInGroup
         FROM   T1)
SELECT one,
       two,
       DENSE_RANK() OVER (ORDER BY MinInGroup) AS BlockNumber
FROM   T2
ORDER  BY one 
于 2013-09-25T11:01:01.950 に答える
1

SQL 2012 より前の分析関数でそれを行う方法は考えられません。ラグの良さがあるかもしれませんが、それらの関数にはまだ慣れていません。

したがって、優先順位が結果セットの生成方法ではなく結果セットである場合は、次を使用します。

;With Blocks as (
    select d1.one,d1.two,ROW_NUMBER() OVER (ORDER BY d1.one) as BlockNumber
    from @data d1
        left join
        @data d2
            on
                d1.two = d2.two and
                d1.one = d2.one + 1
    where d2.one is null
    union all
    select d.one,d.two,b.BlockNumber
    from
        @data d
            inner join
        Blocks b
            on
                d.two = b.two and
                d.one = b.one + 1
) select * from Blocks
order by one

CTE は最初に、前の行と値が異なるすべての行を見つけtwoます。次に、すでに識別された行の直後に同じ値を持つ行を追加し続け、twoそれらに同じブロック番号を割り当てます。

于 2013-09-25T10:31:22.117 に答える