假设我有2个表,如下所示 - 父母和孩子
create table parent
(
parent_id number,
parent_name varchar2(10),
cnt number
)
create table children
(
child_id number,
parent_id number,
name varchar2(10)
)
insert into parent values (1, 'A', 3);
insert into parent values (2, 'B', 2);
insert into children values (1, 1, 'AB');
insert into children values (1, 2, 'AC');
insert into children values (1, 3, 'AD');
insert into children values (2, 1, 'BA');
insert into children values (2, 2, 'BB');
输出必须如下所示:
Parent_ID Parent_Name Cnt Child_Names
1 A 3 AB, AC, AD
2 B 2 BA, BB
我已经编写了以下查询来实现这一目标。我不知道它出错的地方,查询似乎很好,但输出并不是我想要的。
请帮帮我,因为我几乎已经饱和地调试了这个。
select parent_id, parent_name, substr(max(sys_connect_by_path(child_name, ',')),2)
from
( select p.parent_id, p.parent_name, ch.child_name, row_number() over (partition by p.parent_id, p.parent_name order by ch.child_name) rn
from parent p, children ch
where p.parent_id = ch.parent_id
)
start with rn =1
connect by prior rn+1 = rn
group by parent_id, parent_name
答案 0 :(得分:0)
您不会看到层次数据。这是一个简单的主要细节。
select p.parent_id, p.parent_name, p.cnt, c.children_names, c.real_count
from parent p left outer join
(select parent_id, listagg(name, ', ') within group (order by name) children_names,
count(*) real_count from children group by parent_id) c
on p.parent_id = c.parent_id
' AD'没有连接,因为它的parent_id是3。
Hm ... listagg是一个11g的功能。 11g之前的一般解决方案是使用Tom Kyte的方法: http://www.sqlsnippets.com/en/topic-11591.html
并查看http://www.oracle-developer.net/display.php?id=515的表现期望
好的,让我们继续"通过"的形式给出。 首先,让我们忘记父表来降低复杂性。我们将构建上面左外连接查询的右侧,但是通过构造使用连接。
其次,我认为你错过了parent_id和child_id的命名方式。我的猜测是你的child_id实际上是父表中的parent_id。所以名字是错的。
将所有孩子排成一排的3个条件:
所有孩子都有相同的child_id(parent.parent_id)
第一个有parent_id = 1(更像是order_id)
每个下一个都有parent_id +1与前一个
让我们全部查询:
select c.*, level from children c
start with parent_id = 1 --2nd condition
connect by prior
c.parent_id = c.parent_id -1 --3rd condition
and prior child_id = child_id --1st condition
order by child_id, parent_id
然后添加SYS_CONNECT_BY_PATH(名称,','),获取最后一个元素,然后将其与父表连接,但基于parent.parent_id = children.child_id
答案 1 :(得分:0)
这是你的修正后的查询,实际上你在子表的列名中做了一些错误(写了ch.child_name,而它是ch.name或name)
select parent_id, parent_name,cnt,substr(max(sys_connect_by_path(child_name, ',')),2) child_name
from
( select p.parent_id, p.parent_name, p.cnt , ch.name child_name, row_number() over (partition by p.parent_id, p.parent_name order by ch.name) rn
from parent p, children ch
where p.parent_id = ch.parent_id
)
start with rn =1
connect by prior rn+1 = rn
group by parent_name,cnt,parent_id