2016-03-31 51 views
1

我有3個表格:table_Atable_Btable_CTable_A有一個主鍵,並由來自table_B的外鍵引用。 Table_C有一個由table_B的外鍵引用的主鍵。設計是這樣的:獲取多個數據到一個colomn Oracle查詢

 
Table_A: 
ID_A 
TextData 
 
Table_B: 
ID_B 
ID_A 
ID_C 
 
Table C: 
ID_C 
TextData 

我想3臺這樣的之間加入:

 
select A.ID_A, A.TextData as DataA, 
(
    select C.TextData 
    from Table_B B, Table_C C 
    where B.ID_C = C.ID_C and B.ID_A = C.ID_A 
) as Data_C 
from Table_A; 

我知道,如果我嘗試編譯它,它應該是一個錯誤帶有如下錯誤:返回多個元素

但我的客戶想讓我把表C中的所有數據合併成一行,我只知道使用concatep來處理每個數據。但我不知道該怎麼做。我從來沒有嘗試在oracle上創建函數或包。你能幫我解決我的問題嗎?

結果應該是這樣的:

 
ID_A | DataA  | Data_C 
1   texta  text1, text2, text8 
2   textb  text2, text3, text9 
3   textc  text1, text8, text9 
+1

您可以請張貼一些樣本數據和期望的結果嗎? – Aleksej

+0

@Aleksej請檢查編輯帖子,謝謝。 – user3505775

+0

您使用的是哪個版本的Oracle? – Boneist

回答

1

XMLAGG或類似的是你所需要的。喜歡的東西(未測試,但應該給你一個提示):

select A.ID_A, A.TextData as DataA, 
(
    select XMLELEMENT("Thedata",XMLAGG("textdata",C.TextData)) as td 
    from Table_B B, Table_C C 
    where B.ID_C = C.ID_C and B.ID_A = C.ID_A 
) as Data_C 
from Table_A; 

使用替換/翻譯/ REGEXP_REPLACE等,如果需要剝離出XML標記。

有關例如http://www.dba-oracle.com/t_converting_rows_columns.htm

+0

我已經嘗試,但我得到這樣的錯誤:調用'SYS_IXMLAGG – user3505775

+0

'中的錯誤數量或參數類型我認爲發佈的鏈接包含一些可以應用的示例。但也許嘗試XMLAGG(XMLELEMENT(X,c.textdata ||','))而不是XMLELEMENT ... – TenG

+0

X是什麼意思? – user3505775

0

也許你應該寫你的聚合。 Funcrion來連接你的字符串user defined aggregates

或者使用未公開的wm_concat。因此在12c中棄用了函數。

0

如果你在Oracle 11g或更高版本,可以使用LISTAGG

with table_a as (select 1 id_a, 'texta' textdata from dual union all 
       select 2 id_a, 'textb' textdata from dual union all 
       select 3 id_a, 'textc' textdata from dual), 
    table_b as (select 1 id_b, 1 id_a, 1 id_c from dual union all 
       select 2 id_b, 1 id_a, 2 id_c from dual union all 
       select 3 id_b, 1 id_a, 4 id_c from dual union all 
       select 4 id_b, 2 id_a, 2 id_c from dual union all 
       select 5 id_b, 2 id_a, 3 id_c from dual union all 
       select 6 id_b, 2 id_a, 5 id_c from dual union all 
       select 7 id_b, 3 id_a, 1 id_c from dual union all 
       select 8 id_b, 3 id_a, 4 id_c from dual union all 
       select 9 id_b, 3 id_a, 5 id_c from dual), 
    table_c as (select 1 id_c, 'text1' textdata from dual union all 
       select 2 id_c, 'text2' textdata from dual union all 
       select 3 id_c, 'text3' textdata from dual union all 
       select 4 id_c, 'text8' textdata from dual union all 
       select 5 id_c, 'text9' textdata from dual) 
-- end of mimicking your tables; see sql below. 
select a.id_a, 
     a.textdata, 
     listagg(c.textdata, ', ') within group (order by c.id_c) data_c 
from table_a a 
     inner join table_b b on (a.id_a = b.id_a) 
     inner join table_c c on (b.id_c = c.id_c) 
group by a.id_a, a.textdata; 

     ID_A TEXTDATA DATA_C    
---------- -------- -------------------- 
     1 texta text1, text2, text8 
     2 textb text2, text3, text9 
     3 textc text1, text8, text9 
2

你可以用這個嘗試:

SETUP

create table table_A(ID_A number, TextData varchar2(100)) 
/
create table Table_B(ID_B number, ID_A number, ID_C number) 
/
create table Table_C(ID_C number, TextData varchar2(100)) 
/
insert into table_A values (1, 'texta'); 
insert into table_A values (2, 'textb'); 
insert into table_A values (3, 'textc'); 
-- 
insert into table_C values (1, 'text1'); 
insert into table_C values (2, 'text2'); 
insert into table_C values (3, 'text3'); 
insert into table_C values (8, 'text8'); 
insert into table_C values (9, 'text9'); 
-- 
insert into table_b values (11, 1, 1); 
insert into table_b values (12, 1, 2); 
insert into table_b values (18, 1, 8); 
insert into table_b values (22, 2, 2); 
insert into table_b values (23, 2, 3); 
insert into table_b values (29, 2, 9); 
insert into table_b values (31, 3, 1); 
insert into table_b values (38, 3, 8); 
insert into table_b values (39, 3, 8); 

QUERY:

select id_a, a.textData as DataA, listagg(c.textData, ', ') within group (order by c.textData) as Data_c 
from table_A a 
    inner join table_B b 
    using(id_A) 
    inner join table_c c 
    using(id_c) 
group by id_a, a.textData