不知道为什么 wm_concat 对你不起作用,但我怀疑你的级别有误或分组奇怪。
如果我设置一些虚拟数据:
create table issues (id number);
create table owners (id number, first varchar2(10), middle varchar2(10),
last varchar2(10), org varchar2(3));
create table issue_owners (issue_id number, owner_id number);
insert into issues (id) values (1);
insert into issues (id) values (2);
insert into issues (id) values (3);
insert into owners (id, first, middle, last, org)
values (11, 'Sam', null, 'Smith', 'AAA');
insert into owners (id, first, middle, last, org)
values (12, 'Stan', null, 'Bird', 'BBB');
insert into owners (id, first, middle, last, org)
values (13, 'Nancy', null, 'Bird', 'BBB');
insert into owners (id, first, middle, last, org)
values (14, 'Mike', null, 'Owen', 'CCC');
insert into issue_owners (issue_id, owner_id) values (1, 11);
insert into issue_owners (issue_id, owner_id) values (2, 12);
insert into issue_owners (issue_id, owner_id) values (2, 13);
insert into issue_owners (issue_id, owner_id) values (3, 14);
...它提供与配对样本相同的初始输出:
column issue_id format 9 heading "#"
column owner format a50 heading "Owner"
select i.id as issue_id,
o.first
|| case when o.middle is null then null else ' ' || o.middle end
|| ' ' || last || ', ' ||o.org as owner
from issues i
left join issue_owners io on io.issue_id = i.id
left join owners o on o.id = io.owner_id
order by issue_id, owner;
# Owner
-- --------------------------------------------------
1 Sam Smith, AAA
2 Nancy Bird, BBB
2 Stan Bird, BBB
3 Mike Owen, CCC
4 rows selected.
我可以使用wm_concat 来聚合名称:
select issue_id,
replace(cast(wm_concat(owner_name) as varchar2(4000)), ',', ', ')
|| ', ' || owner_org as owner
from (
select i.id as issue_id,
o.first
|| case when o.middle is null then null else ' ' || o.middle end
|| ' ' || last as owner_name,
o.org as owner_org
from issues i
left join issue_owners io on io.issue_id = i.id
left join owners o on o.id = io.owner_id
)
group by issue_id, owner_org
order by issue_id, owner;
# Owner
-- --------------------------------------------------
1 Sam Smith, AAA
2 Stan Bird, Nancy Bird, BBB
3 Mike Owen, CCC
3 rows selected.
replace 只是在名称之间放置空格,这并不完全相关,我将 casting 到 varchar2,因为 wm_concat 返回一个 clob,这会导致连接org。至少,它是 11gR2 中的 clob - 我没有可用的 wm_concat 的 10g 实例,但我认为它在早期版本中返回 varchar2;如果是这样,则不需要cast,它更像是:
select issue_id,
replace(wm_concat(owner_name), ',', ', ') || ', ' || owner_org as owner
from (
...
我不确定您的 org 值来自何处,因此这可能已简化,并且我不知道如果 org 与一个人相关联(而不是问题,或您的等价物)并且一个问题有两个拥有不同 org 值的所有者。
如果这没有让您更接近,那么也许您可以发布查询的精简版本,用一些固定数据替换长的多表部分,并展示您如何尝试使用 wm_concat 反对它;或您自己的显示相同行为的示例数据构建版本。
建议 Appleman1234 的替代 sys_connect_by_path 方法,用于相同的数据:
select issue_id,
ltrim(max(sys_connect_by_path(owner_name, ', '))
keep (dense_rank last order by curr), ', ')
|| ', ' || owner_org as owner
from (
select issue_id,
owner_name,
owner_org,
row_number() over (partition by issue_id order by owner_name) as curr,
row_number() over (partition by issue_id order by owner_name) - 1 as prev
from (
select i.id as issue_id,
o.first
|| case when o.middle is null then null else ' ' || o.middle end
|| ' ' || last as owner_name,
o.org as owner_org
from issues i
left join issue_owners io on io.issue_id = i.id
left join owners o on o.id = io.owner_id
)
)
group by issue_id, owner_org
connect by prev = prior curr and issue_id = PRIOR issue_id
start with curr = 1;
# Owner
-- --------------------------------------------------
1 Sam Smith, AAA
2 Nancy Bird, Stan Bird, BBB
3 Mike Owen, CCC
3 rows selected.
如果你最终使用了它,Appleman1234 应该添加一个答案,我会删除这部分,因为他的建议应该得到赞誉!反正我也想试试,以前看过但不记得了……