2015-10-15 26 views
1

我有一個表這樣的數據:爲什麼多行不連接?

ID  ANIMAL 
555000 Dog 
555000 Cow 
555000 Fox 
657000 Fox 
817900 Dog 
817900 Fox 
829800 Fox 
830300 Fox 
830600 Fox 
830800 Fox 
831100 Dog 
831100 Fox 
839900 Fox 

我需要創建輸出由ID組,然後創建標識的動物的分隔字符串。鑑於上述數據,我需要以下輸出。請注意,每個ID應該是結果集中的一個單獨的行,並且動物應該連接成每個ID的單個字符串。我不想創建一個大的連接字符串。

555000 Dog<br/>Cow<br/>Fox 
657000 Fox 
817900 Dog<br/>Fox 
829800 Fox 
830300 Fox 
830600 Fox 
830800 Fox 
831100 Dog<br/>Fox 
839900 Fox 

這是我到目前爲止的SQL。它爲每個ID,ANIMAL組合產生一行。問題是ANIMAL字段中的值沒有被連接。我究竟做錯了什麼?

select ID, 
     REPLACE (wm_concat (DISTINCT ANIMAL),',','<br/>') 
from TheTable 
group by ID, ANIMAL 
+0

您的'通過ID,ANIMAL組'確保每行只有一個不同的動物。從「group by」組中刪除「ANIMAL」列,它將起作用。 –

+0

@ WumpusQ.Wumbley - 是的,就是這樣。我在下面的gustavodidomenico發佈的鏈接上查找wm_concat示例時發現我的錯誤。 – DenaliHardtail

回答

1

使用LISTAGG解析函數:

SELECT ID, LISTAGG(ANIMAL, '<br/>') WITHIN GROUP (ORDER BY ANIMAL) animals 
FROM TheTable 
GROUP BY ID; 

注意:您將被限制在4000 字節

編輯:

沒有爲字符串聚合技術一個很好的資源:

https://oracle-base.com/articles/misc/string-aggregation-techniques#user_defined_aggregate_function

+1

明智的建議 - 但是,應該記住,如果連接字符串變得太長(> 4000個字符),LISTAGG就會完全失敗。 –

+0

@FrankSchmitt,這對我來說是新的。謝謝你指出。 – gustavodidomenico

+0

這就是我現在遇到的,但我不明白我們如何可以接近4000個字符... – DenaliHardtail

0

一種方法是使用XMLAGG/XMLELEMENT代替LISTAGG(這將避免可怕的ORA-01489:結果字符串連接太長):

select ID, 
    RTRIM(XMLAGG(XMLELEMENT(E, 
          t.animal || ',')).EXTRACT('//text()').getclobval(), 
     ',') as animals 
from theTable t 
group by ID 

This

  • 每隻動物轉換成XML節點(使用XMLELEMENT
  • 使用EXTRACTgetClobVal()
  • 去除聚集使用XMLAGG和串並置運算符||
  • 擺脫的XML東西的XML元素尾隨逗號RTRIM

SQL Fiddle

IIRC有一個稍微更優雅的方式使用XMLCAST而不是EXTRACT/getClobVal,但我現在無法訪問我的代碼庫來檢查它。

相關問題