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个条件:

  • 所有子项都具有相同的子项id(parent.parent\u id)

  • 第一个具有父\u id=1(更像订单\u id)

  • 与前一个相比,每个下一个都有父_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\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