对于必须使用 Oracle 9i(或更早版本)解决此问题的用户,您可能需要使用 SYS_CONNECT_BY_PATH,因为 LISTAGG 不可用。
为了回答 OP,以下查询将显示表 A 中的 PID 并连接表 B 中的所有 DESC 列:
SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
FROM (
SELECT a.pid, seq, description
FROM table_a a, table_b b
WHERE a.pid = b.pid(+)
)
)
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;
也可能存在键和值都包含在一个表中的情况。在没有表 A 且只存在表 B 的情况下,可以使用以下查询:
SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
FROM (
SELECT pid, seq, description
FROM table_b
)
)
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;
所有值都可以根据需要重新排序。单独的连接描述可以在 PARTITION BY 子句中重新排序,PID 列表可以在最终的 ORDER BY 子句中重新排序。
或者:有时您可能希望将整个表中的所有值连接到一行中。
这里的关键思想是为要连接的描述组使用人工值。
在以下查询中,使用了常量字符串 '1',但任何值都可以:
SELECT SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
SELECT ROW_NUMBER () OVER (PARTITION BY unique_id ORDER BY pid, seq) rnum, description
FROM (
SELECT '1' unique_id, b.pid, b.seq, b.description
FROM table_b b
)
)
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1;
可以在 PARTITION BY 子句中重新排序各个连接描述。
此页面上的其他几个答案也提到了这个非常有用的参考:
https://oracle-base.com/articles/misc/string-aggregation-techniques