2011-03-16 41 views
4

我有一個名爲「person」的表。它包含個人的ID和它的父母身份(只有一個父母是可能的)。作爲查詢的結果,我想要一個帶有第一列的表格 - 一個人員ID,第二列 - 它的孩子ID列表。如何做到這一點?我已閱讀了關於listagg函數,但我不確定它是否適合我的目的。 而這個查詢產生一個空的第二列:由於Oracle中的SELECT語句導致的逗號分隔列表

選擇t1.id, 從人T1 (來自人T2 其中t2.parent_id = t1.id選擇t2.id)其中t1.status = '父' ;

+1

希望只第一代的孩子在列表中? – 2011-03-16 12:40:30

+0

是的,只有第一個 – 2011-03-16 20:43:36

回答

7
SELECT parent_id, 
     RTRIM(XMLAGG(XMLELEMENT(e,child_id || ',')).EXTRACT('//text()'),',') AS "Children" 
    FROM parentChildTable 
WHERE parent_id = 0 
GROUP BY parent_id 

SELECT parent_id, 
     LISTAGG(child_id, ',') WITHIN GROUP (ORDER BY child_id) AS "Children" 
    FROM parentChildTable 
WHERE parent_id = 0 
GROUP BY parent_id 
+1

同意馬克,如果你在11gr2 ListAgg是你想要的 – Harrison 2011-03-16 12:50:38

+0

謝謝,但我認爲我給了我的問題一個錯誤的例子。我的問題是,如果一個錶行包含ID,數字(每個孩子都有其父母的編號)和狀態(狀態可以是孩子或父母),如何查詢第一列的表 - 一個人的ID和第二列 - 它的孩子ID的列表? – 2011-03-17 07:12:43

+0

@腦損傷 - 你現在失去了我。我給出的兩個查詢都應該完全按照您似乎要求的方式執行......只是刪除指定單個父項的WHERE子句(您可能希望使用WHERE子句,其中status ='paerent')。 – 2011-03-17 08:35:36

0

只是另一種方式接近它...

SELECT parent_id,max(child_list) FROM (
    SELECT parent_id,sys_connect_by_path(child_number,',') child_list FROM (
    SELECT parent_id, id, 
      row_number() over (partition by parent_id order by id) child_number 
     FROM person 
     WHERE parent_id IS NOT NULL 
) 
    START WITH child_number=1 
    CONNECT BY parent_id = PRIOR parent_id AND child_number = PRIOR child_number + 1 
) 
GROUP BY parent_id 
ORDER BY parent_id 
; 
1

馬克的實施LISTAGG的肯定是要走對於Oracle 11gR2的方式。對於11GR1或Oracle 10,您可以使用wmsys.wm_Concat完全相同的方式(可能需要從您的DBA獲得權限授予)

相關問題