2013-01-22 198 views
1

我有一個包含大約一百萬條記錄的表。幾個樣本值在下面給出:SQL查詢將連續的數字範圍分組到不同的分組集

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

在您鏈接的問題,接受的答案很可能是這樣做的最有效的方式。需要多長時間?您需要多長時間?執行計劃是什麼樣的?你有'Group,MemberNo'的索引嗎? –

+0

嗨@MartinSmith,還有4列,爲簡單起見,我只添加了一列。我已經索引所有這些列,但仍然需要4到5秒的查詢。 – Nagesh

+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 
) 
+0

謝謝,但@Andriy M的解決方案只需很少的tweeking! – Nagesh