【发布时间】:2020-12-11 22:08:42
【问题描述】:
| A | B |
|---|---|
| a1 | b1 |
| a2 | b1 |
| a3 | b2 |
| a4 | b2 |
| a5 | b2 |
| a6 | b3 |
在上面这样的 SQL 表中,我想编写一个查询来得到以下结果
b1: a1,a2
b2: a3,a4,a5
b3: a6
假设所有的值都是 varchar
【问题讨论】:
| A | B |
|---|---|
| a1 | b1 |
| a2 | b1 |
| a3 | b2 |
| a4 | b2 |
| a5 | b2 |
| a6 | b3 |
在上面这样的 SQL 表中,我想编写一个查询来得到以下结果
b1: a1,a2
b2: a3,a4,a5
b3: a6
假设所有的值都是 varchar
【问题讨论】:
listagg 函数应该可以解决问题:
SELECT b, LISTAGG(a, ',') WITHIN GROUP (ORDER BY a)
FROM mytable
GROUP BY b
【讨论】:
原则上,数据应按B 列分组,串联应应用于A 列。
如果 DB 的版本是 11gR2+,那么 LISTAGG() 函数可能是
应用:
SELECT B,
LISTAGG(A, ',') WITHIN GROUP
( ORDER BY TO_NUMBER( REGEXP_REPLACE(A,'[^0-9]')) ) AS "Concatenated String"
FROM tab
GROUP BY B
ORDER BY B
如果 DB 版本是 11gR2-,则 XMLAGG(XMLELEMENT())
可能会应用功能组合:
SELECT B,
RTRIM(DBMS_XMLGEN.CONVERT(
XMLAGG(
XMLELEMENT(e,A||',')
).EXTRACT('//text()').GETCLOBVAL() ,1),
',') AS "Concatenated String"
FROM tab
GROUP BY B
ORDER BY B
特殊情况如果 ORA-01489: 字符串连接的结果太长,每当第一个参数中的连接字符串超过了 4000 个字符的长度,发生:
上述第二种情况适用。如果DB的版本是12gR2+,那么第一种情况可能被用作
SELECT B,
LISTAGG(A, ',' ON OVERFLOW TRUNCATE 'THE REST IS TRUNCATED' WITHOUT COUNT )
WITHIN GROUP
( ORDER BY TO_NUMBER( REGEXP_REPLACE(A,'[^0-9]')) ) AS "Concatenated String"
FROM tab
GROUP BY B
ORDER BY B
为了截断尾部而不出现错误ORA-01489。
【讨论】: