0

次の表があります。

|id|sog|zoneId|
| 1| 20|     2|
| 2|  2|     2|
| 3| 10|     2|
| 4| 10|     1|
| 5|  3|     1|
| 6| 8 |     2|
| 7| 1 |     2|
| 8| 3 |     2|
| 9| 4 |     2|

行は列でソートされidます。

返すクエリを作成したい:

|id|sog|zoneId|grpId|
| 1| 20|     2|    1|
| 2|  2|     2|    1|
| 3| 10|     2|    1|
| 4| 10|     1|    2|
| 5|  3|     1|    2|
| 6| 8 |     2|    3|
| 7| 1 |     2|    3|
| 8| 3 |     2|    3|
| 9| 4 |     2|    3|
4

2 に答える 2

1

あなたのIDがシーケンシャルでギャップがない場合、最速の方法は次のようになると思います:

;with cte as (
    select
        T.id, T.sog, T.zoneId,
        1 as grpId
    from Table1 as T
    where T.id = 1

    union all

    select
        T.id, T.sog, T.zoneId,
        c.grpId + case when T.zoneId = c.zoneId then 0 else 1 end as grpId
    from cte as c
        inner join Table1 as T on T.id = c.id + 1
)
select c.id, c.sog, c.zoneId, c.grpId
from cte as c

SQL フィドルのデモ

Id が連続していないか、ギャップがある場合は、次のことができます。

;with cte1 as (
    select
        T.id, T.sog, T.zoneId,
        row_number() over (order by T.id) as row_num
    from Table1 as T
), cte2 as (
    select
        T.id, T.sog, T.zoneId, T.row_num,
        1 as grpId
    from cte1 as T
    where T.row_num = 1

    union all

    select
        T.id, T.sog, T.zoneId, T.row_num,
        c.grpId + case when T.zoneId = c.zoneId then 0 else 1 end as grpId
    from cte2 as c
        inner join cte1 as T on T.row_num = c.row_num + 1
)
select c.id, c.sog, c.zoneId, c.grpId
from cte2 as c

SQL フィドルのデモ

しかし、パフォーマンスがそのために良いかどうかはわかりません

于 2013-08-12T06:28:52.750 に答える