我必须从同一个表中提取一对多的关系数据。 表的结构就像
____________________________________
| CUSTOMER_ID | SUBSCRIPTION_NAME |
-------------------------------------
| 1 | ABC |
| 1 | TNT |
| 1 | AMC |
| 2 | ABC |
| 2 | USA |
| 3 | TNT |
| 3 | AMC |
-------------------------------------
我想得到像
这样的输出 | CUSTOMER_ID | SUBSCRIPTION_NAME |
| 1 | ABC,TNT,AMC |
| 2 | ABC,USA |
| 3 | TNT,AMC |
答案 0 :(得分:3)
SELECT customer_id,
LISTAGG(subscription_name, '; ') WITHIN GROUP (ORDER BY subscription_name) AS subscription_name
FROM subscription
GROUP BY customer_id
ORDER BY customer_id;
Order by是可选的
答案 1 :(得分:0)
LISTAGG的几个替代品:
SQL> with t (CUSTOMER_ID, SUBSCRIPTION_NAME)
2 as (
3 select 1, 'ABC' from dual union all
4 select 1, 'TNT' from dual union all
5 select 1, 'AMC' from dual union all
6 select 2, 'ABC' from dual union all
7 select 2, 'USA' from dual union all
8 select 3, 'TNT' from dual union all
9 select 3, 'AMC' from dual
10 )
11 SELECT CUSTOMER_ID,
12 RTRIM(
13 XMLAGG (XMLELEMENT(e, SUBSCRIPTION_NAME||',') ORDER BY SUBSCRIPTION_NAME).EXTRACT('//text()')
14 ,',') AS x
15 FROM t
16 GROUP BY CUSTOMER_ID
17 /
CUSTOMER_ID X
----------- ----------------------------------------
1 ABC,AMC,TNT
2 ABC,USA
3 AMC,TNT
SQL> with t (CUSTOMER_ID, SUBSCRIPTION_NAME)
2 as (
3 select 1, 'ABC' from dual union all
4 select 1, 'TNT' from dual union all
5 select 1, 'AMC' from dual union all
6 select 2, 'ABC' from dual union all
7 select 2, 'USA' from dual union all
8 select 3, 'TNT' from dual union all
9 select 3, 'AMC' from dual
10 )
11 select customer_id,
12 max(substr(sys_connect_by_path( SUBSCRIPTION_NAME, ','),2)) x from
13 (
14 select customer_id, SUBSCRIPTION_NAME, row_number() over(partition by customer_id order by null) rn
15 from t
16 )
17 start with rn=1
18 connect by prior customer_id = customer_id and rn = prior rn+1
19 group by customer_id
20 /
CUSTOMER_ID X
----------- ----------------------------------------
1 ABC,TNT,AMC
2 ABC,USA
3 TNT,AMC