Oracle 通过事先给出错误结果进行连接
假设我有如下所示的两个表——父表和子表Oracle 通过事先给出错误结果进行连接,oracle,oracle10g,hierarchical-data,Oracle,Oracle10g,Hierarchical Data,假设我有如下所示的两个表——父表和子表 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
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
你看不到层次数据。它是简单的掌握细节
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”未连接,因为它的父项id为3
嗯。。。listagg是11g的一个特性。
11g之前的一般解决方案是使用Tom Kyte的aproach:
并查看性能预期
好的,让我们继续“连接方式”一词。
首先,让我们通过忘记父表来降低复杂性。我们将在上面构建左侧外部联接查询的右侧,但使用connect by构造
第二,我想你错过了父母id和孩子id的命名方式。我猜您的子id实际上是父表中的父id。所以这个名字是错的
将所有子项排成一行的3个条件:
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\u CONNECT\u BY_PATH(name,,),获取最后一个元素,然后将其与父表联接,但基于parent.parent\u id=children.children\u id这是更正后的查询,实际上您在children表的列名中犯了一些错误(当它是ch.name或name时写了ch.children\u name)
任何擅长分层查询的人请帮助我。感谢VAV提供的listagg函数。但我使用的是Oracle 10g,我想知道使用的sys\u connect\u by\u path函数有什么问题。不知怎的,我得到了一个错误的输出。查询似乎很好,不确定我是否遗漏了查询中的任何内容?请帮忙。。
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