SQL Query将连续的数字范围分组到不同的分组集中

时间:2013-01-22 12:43:11

标签: tsql sql-server-2005 gaps-and-islands

我的桌面记录大约有一百多万张。以下给出了几个样本值:

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.我已经尝试this线程并且对我来说工作正常。但这需要相当长的时间 请帮助我实现这一目标。

提前致谢。

1 个答案:

答案 0 :(得分:1)

另一种解决方案。我可以看一下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
)