2016-02-28 22 views
3

,我有以下數據:如何ignorre來自相同組連續記錄與SQL

ItemID | ProdID | ItemTypeID 
=======+========+=========== 
1001 | 100 | A 
1002 | 100 | B 
1003 | 100 | A 
1004 | 100 | B 
1005 | 100 | B <- successive itemtype (should be excluded) 
1006 | 100 | C 
1007 | 200 | C 
1008 | 200 | A 

,我想每個組內,但沒有相同的ID連續列出ItemTypeIDs(LISTAGG)。所以我的結果應該是這樣的:

ProdID | ItemTypes 
=======+========== 
100 | A,B,A,B,C <- not A,B,A,B,B,C (successive B) 
200 | C,A 

回答

1

這很棘手。 Listagg()甚至不允許distinct,所以所有的工作都需要在子查詢中完成。

您可以使用行號方法的差異來識別連續的ItemTypeId。然後,一旦羣體被識別,則可以通過組聚集和然後listagg()

select ProdId, 
     listagg(ItemId, ',') within group (order by seqnum) as items 
from (select ProdId, ItemId, count(*) as NumItems, 
      row_number() over (partition by ProdId order by min(ItemId)) as seqnum 
     from (select t.*, 
        (row_number() over (partition by ProdId order by ItemId) - 
        row_number() over (partition by ProdId, ItemTypeId order by ItemId) 
        ) as grp 
      from t 
      ) t 
     group by ProdId, ItemTypeId, grp 
    ) t 
group by ProdId; 

編輯:

另一種方式來處理這個使用lag()尋找到新的羣體開始。以前的方法可以讓你獲得計數。這種方法可能會更容易理解:

select ProdId, 
     listagg(ItemId, ',') within group (order by ItemId) as items 
from (select t.* 
     from (select t.*, 
        lag(ItemTypeId) over (partition by ProdId order by ItemId) as prev_ItemTypeId 
      from t 
      ) t 
     where prev_ItemTypeId is null or prev_ItemTypeId <> ItemTypeId 
    ) t 
group by ProdId; 
+0

您能否給出一點提示您在哪裏提出了有關窗口函數結果的計算?它似乎不是一分鐘就能提出的解決方案。你必須有這種想法的經驗。我很好奇這個方法是否有一些知識基礎。我已經看到你的答案與這樣的創作:-) –

+0

@ConsiderMe。 。 。從第二個查詢開始。我認爲邏輯更容易遵循。至於第一個,它只是要求列出中間結果以查看行號之間的差異(在我的書「使用SQL和Excel的數據分析」中有一個例子)。 –

+0

謝謝,我一定會檢查出來的。帶有'lag()'的解決方案首先出現在我的腦海裏。我沒有拿出row_number減法。 –