2017-03-16 45 views
0

我具有下列 - 簡化 - 爲表佈局:的Oracle SQL骨料行到塔LISTAGG與條件

  • 表塊(ID)
  • 表內容(ID,BLOCKID,命令,數據,類型)

content.blockIdblocks.id的外鍵。這個想法是,在內容表中,一個塊有很多不同類型的內容條目。

我現在正在查找一個查詢,該查詢可以根據blockId提供一個聚合,其中3種不同類型的所有內容條目都連接在一起並放入相應的列中。

我已經開始,發現listagg功能,運作良好,我做了下面的語句,並列出了我一列中的所有內容條目:

SELECT listagg(c.data, ',') WITHIN GROUP (ORDER BY c.order) FROM content c WHERE c.blockId = 330; 

現在連接字符串但是包含了所有的data一列中的塊的元素。我想實現的是它根據類型將其放入單獨的列中。例如content以下內容會是這樣:

  • 1,1,0, 「內容1」, 「片段」
  • 2,1,1, 「內容2」, 「大量」
  • 3,1,3, 「content4」, 「片段」
  • 4,1,2, 「content3」, 「片段」

現在我想獲得作爲輸出2列,一種是片段和一個是BULK,其中FRAGMENT包含「content1; content3; content4」,BULK包含「content2」

有沒有一種有效的方法來實現這一目標?

回答

1

您可以使用case

SELECT listagg(CASE WHEN content = 'FRAGMENT' THEN c.data END, ',') WITHIN GROUP (ORDER BY c.order) as fragments, 
     listagg(CASE WHEN content = 'BULK' THEN c.data END, ',') WITHIN GROUP (ORDER BY c.order) as bulks 
FROM content c 
WHERE c.blockId = 330; 
+0

多數民衆贊成在這裏,謝謝,你碰巧知道如果我的WHERE不是= 350但是例如> 350是否也有可能獲得每塊一行?我嘗試使用'OVER(PARTITION BY c.blockId)',它現在爲每個blockId創建行,但是每個條目連接一行,就像有25個片段有25個行具有相同的內容。 –

+0

@YanickSalzmann。 。 。你應該提出新的問題作爲*問題*,而不是*評論*。 –

1

作爲替代方案,如果你想讓它更加動態,你可以轉動的結果。 請注意,這隻適用於Oracle 11.R2。 Here's一個例子怎麼可能是這樣的:

select * from 
(with dataSet as (select 1 idV, 1 bulkid, 0 orderV, 'content1' dataV, 'FRAGMENT' typeV from dual union 
       select 2, 1, 1, 'content2', 'BULK' from dual union 
       select 3, 1, 3, 'content4', 'FRAGMENT' from dual union 
       select 4, 1, 2, 'content3', 'FRAGMENT' from dual) 
select typeV, listagg(dataSet.dataV ,',') WITHIN GROUP (ORDER BY orderV) OVER (PARTITION BY typeV) dataV from dataSet) 
pivot 
(
    max(dataV) 
    for typeV in ('BULK', 'FRAGMENT') 
) 

O/P

Bulk  | FRAGMENT 
----------------- 
content2 | content1,content3,content4 

這裏最重要的事情:

OVER (PARTITION BY typeV):這就像一組通過爲LISTAGG,concatinating一切都有相同的typeV

for typeV in ('BULK', 'FRAGMENT'):這將收集BULKFRAGMENT的數據,併爲每個數據生成單獨的列。

max(dataV)只是爲了提供一個聚合函數,否則pivot不會工作。