在Oracle中,选择语句的结果是逗号分隔的列表。

5
我有一个名为“person”的表格,其中包含 person 的 id 和其父母的 id(只有一个父母)。作为查询结果,我希望得到一个表格,第一列是 person id,第二列是其子代 id 列表。如何实现这一点?我已经阅读了 listagg 函数,但我不确定它是否适用于我的目的。

而且这个查询产生了一个空的第二列:

select t1.id, (select t2.id from person t2 where t2.parent_id = t1.id) from person t1 where t1.status = 'parent';


1
你只想要列表中的第一代子元素吗? - Dave Costa
4个回答

9
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,那么我同意Mark的观点,ListAgg正是你需要的。 - Harrison
谢谢,但我想我给出了错误的问题示例。我的问题是,如果一个表行包含id、number(每个子代都有其父代的number)和status(status可以是child或parent),如何为具有第一列-人员id和第二列-其子代id列表的表进行查询? - brain_damage
@brain-damage - 现在我有点懵了。我给出的两个查询应该都能够完全满足你所要求的...只需删除指定单个父级的WHERE子句即可(你可能需要使用一个WHERE子句,其中status = 'parent')。 - Mark Baker
如果这不是您想要的内容,也许提供一些表格数据示例以及您想要实现的结果会帮助我们更好地理解。 - Mark Baker

1

Mark的LISTAGG实现绝对是ORacle 11GR2的最佳选择。对于11GR1或Oracle 10,您可以以完全相同的方式使用wmsys.wm_Concat(可能需要DBA授予权限)。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接