2

約 100 万件を超えるレコードを含むテーブルがあります。サンプル値の一部を以下に示します。

Group    MemberNo
ABC           100
ABC           101
ABC           200
ABC           201
ABC           202
ABC           203
XYZ           100
XYZ           101
ABC           204
XYZ           301
XYZ           302
ABC           500
ABC           600

同じグループの値の連続範囲を次のようなセットにグループ化したいと思います。

Group  FromMemberNo      ToMemberNo
ABC             100             101
ABC             200             204
XYZ             100             101
XYZ             301             302
ABC             500             500
ABC             600             600

上記の表から、100 と 101 は連続しているため、ABC 100 から 101 の 1 つのレコードにグループ化されていることがわかります。このスレッドを試してみたところ、うまく機能しています。しかし、希望よりもかなり長い時間がかかっています。
これを達成するのを手伝ってください。

前もって感謝します。

4

1 に答える 1

2

別の解決策。私はperfsについて理解することができますが、それは仕事をしているようです(SQL 2012のみ)

declare @t table (g varchar(3), mn int)

insert into @t values 
('ABC',           100),
('ABC',           101),
('ABC',           200),
('ABC',           201),
('ABC',           202),
('ABC',           203),
('XYZ',           100),
('XYZ',           101),
('ABC',           204),
('XYZ',           301),
('XYZ',           302),
('ABC',           500),
('ABC',           600),
('XYZ',           400);


with ctet as (
    select 
        row_number() over (order by g, mn) rn,
        *, 
        case when lag(mn, 1) over (order by g, mn) <> mn - 1 then 1 else 0 end as d 
    from 
        @t
)

select g, min(mn), max(mn)
from
    (
    select 
        *,
        (select sum(d) from ctet vv where vv.rn <= ctet.rn) s
    from 
        ctet
    ) v
group by g, s

ラグまたはリードを使用したよりスマートなソリューションがあると確信していますが、それを見つけることができません。

=====編集=====

最終的に2005年にも機能します

 with ctet as (
    select 
        row_number() over (order by t.g, t.mn) rn,
        t.*, 
        case when tt.g is null then 1 else 0 end as d
    from 
        @t t
        left join @t tt on t.g = tt.g and t.mn = tt.mn + 1
)
于 2013-01-22T14:43:13.480 に答える