我有两个看起来像这样的表:
table1
id rs_id
1 1001
2 2001
table2
rs_id rs_name
1001 aaa
1001 bbb
2001 aaa
2001 bbb
2001 ccc
期望的输出:
id rs_id rs_name1 rs_name2 rs_name3 rs_name4
1 1001 aaa bbb
2 2001 aaa bbb ccc
有人可以帮忙吗?
答案 0 :(得分:2)
假设您知道列数,您基本上试图pivot
您的结果。一种选择是使用条件聚合。但是,您没有要聚合的字段。
以下是使用row_number()
创建此类字段的一种方法:
select id,
rs_id,
max(case when rn = 1 then rs_name end) rs_name_1,
max(case when rn = 2 then rs_name end) rs_name_2,
max(case when rn = 3 then rs_name end) rs_name_3,
max(case when rn = 4 then rs_name end) rs_name_4
from (
select t1.id,
t1.rs_id,
t2.rs_name,
row_number() over (partition by t1.id, t1.rs_id order by t2.rs_name) rn
from table1 t1
join table2 t2 on t1.rs_id = t2.rs_id
) t
group by id, rs_id
如果您不知道列数,则需要使用动态SQL来构建列表。
答案 1 :(得分:0)
这是一个适用于Oracle 10g和Oracle 11g的解决方案。我假设你的最大列数为4.类似的解决方案可以用PIVOT
计算出来;如果你想要一个动态解决方案,那么你需要使用PL / SQL。
SELECT id, rs_id
, MAX(CASE WHEN rn = 1 THEN rs_name END) AS rs_name1
, MAX(CASE WHEN rn = 2 THEN rs_name END) AS rs_name2
, MAX(CASE WHEN rn = 3 THEN rs_name END) AS rs_name3
, MAX(CASE WHEN rn = 4 THEN rs_name END) AS rs_name4
FROM (
SELECT t1.id, t1.rs_id, t2.rs_name, ROW_NUMBER() OVER ( PARTITION BY t1.id ORDER BY t2.rs_name ) AS rn
FROM table1 t1 INNER JOIN table2 t2
ON t1.rs_id = t2.rs_id
) GROUP BY id, rs_id;
答案 2 :(得分:0)
第一个解决方案:
SELECT id, rs_id
, MAX(CASE WHEN rn = 1 THEN rs_name END) AS rs_name1
, MAX(CASE WHEN rn = 2 THEN rs_name END) AS rs_name2
, MAX(CASE WHEN rn = 3 THEN rs_name END) AS rs_name3
, MAX(CASE WHEN rn = 4 THEN rs_name END) AS rs_name4
FROM (
SELECT t1.id, t1.rs_id, t2.rs_name, ROW_NUMBER() OVER ( PARTITION BY t1.id ORDER BY t2.rs_name ) AS rn
FROM table1 t1 INNER JOIN table2 t2
ON t1.rs_id = t2.rs_id
) GROUP BY id, rs_id;
第二个解决方案:
SELECT id, rs_id,
REGEXP_SUBSTR (rsname_list, '[^,]+', 1, 1) AS rs_name1,
REGEXP_SUBSTR (rsname_list, '[^,]+', 1, 2) AS rs_name2,
REGEXP_SUBSTR (rsname_list, '[^,]+', 1, 3) AS rs_name3,
REGEXP_SUBSTR (rsname_list, '[^,]+', 1, 4) AS rs_name4
FROM
(
SELECT a.id,
a.rs_id,
LISTAGG (
b.rs_name, ','
) WITHIN GROUP (
ORDER BY b.rs_name
) AS rsname_list
FROM test_table1 a
LEFT JOIN test_table2 b ON a.rs_id = b.rs_id
GROUP BY a.id,a.rs_id
ORDER BY a.rs_id
);