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

I can't think of a way to do it with the analytic functions from before SQL 2012 - there may be some Laggy goodness but I'm not that comfortable with those functions yet.

So, if the priority is the result set rather than how it's produced, I'd use:

;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

The CTE first finds every row which differs from the previous row by its two value. We then keep adding any rows which immediately succeed already identified rows and have the same two value and assign them the same Block number.

于 2013-09-25T10:31:22.117 回答
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 回答