Oracle 12c是否有内置函数实现逗号分隔值分组转行?
在Oracle 12c中实现逗号分隔字符串拆分与聚合的方案
当然可以!Oracle 12c自带的内置函数完全能搞定这个需求,主要靠REGEXP_SUBSTR(拆分字符串)、LISTAGG(聚合结果),再配合CONNECT BY生成拆分所需的行,就能实现你要的输出效果。
核心思路拆解
- 拆分逗号分隔字符串:用
REGEXP_SUBSTR配合CONNECT BY把每行的input_name和input_values拆成单独的元素,同时过滤掉末尾逗号产生的空值。 - 聚合前三条记录:把前三个行的名称、值分别按原顺序拼接成空格分隔的字符串。
- 处理倒序值:对第四行的值按拆分后的位置倒序聚合,得到
400 300 200 100的结果。
完整实现SQL
-- 合并输出三行期望结果 SELECT LISTAGG(name_item, ' ') WITHIN GROUP (ORDER BY rn, pos) AS result FROM ( -- 拆分前三条的input_name,保留行顺序和元素位置 SELECT TRIM(REGEXP_SUBSTR(t.input_name, '[^,]+', 1, LEVEL)) AS name_item, ROW_NUMBER() OVER (ORDER BY t.rowid) AS rn, LEVEL AS pos FROM t1 t WHERE t.rowid NOT IN (SELECT rowid FROM t1 WHERE input_name = 'd,c,b,a,') CONNECT BY LEVEL <= REGEXP_COUNT(t.input_name, '[^,]+') AND PRIOR t.input_name = t.input_name AND PRIOR SYS_GUID() IS NOT NULL ) UNION ALL SELECT LISTAGG(value_item, ' ') WITHIN GROUP (ORDER BY rn, pos) AS result FROM ( -- 拆分前三条的input_values,保留行顺序和元素位置 SELECT TRIM(REGEXP_SUBSTR(t.input_values, '[^,]+', 1, LEVEL)) AS value_item, ROW_NUMBER() OVER (ORDER BY t.rowid) AS rn, LEVEL AS pos FROM t1 t WHERE t.rowid NOT IN (SELECT rowid FROM t1 WHERE input_name = 'd,c,b,a,') CONNECT BY LEVEL <= REGEXP_COUNT(t.input_values, '[^,]+') AND PRIOR t.input_values = t.input_values AND PRIOR SYS_GUID() IS NOT NULL ) UNION ALL SELECT LISTAGG(value_item, ' ') WITHIN GROUP (ORDER BY pos DESC) AS result FROM ( -- 拆分第四行的input_values,按位置倒序聚合 SELECT TRIM(REGEXP_SUBSTR(t.input_values, '[^,]+', 1, LEVEL)) AS value_item, LEVEL AS pos FROM t1 t WHERE t.input_name = 'd,c,b,a,' CONNECT BY LEVEL <= REGEXP_COUNT(t.input_values, '[^,]+') AND PRIOR t.input_values = t.input_values AND PRIOR SYS_GUID() IS NOT NULL );
关键函数说明
REGEXP_SUBSTR:按正则表达式[^,]+提取每个非逗号分隔的元素,LEVEL参数指定提取第几个元素。REGEXP_COUNT:统计字符串中有效元素的数量,用来确定拆分需要生成多少行。LISTAGG:把拆分后的多行元素聚合为单个字符串,WITHIN GROUP (ORDER BY ...)保证元素顺序和原字符串一致。CONNECT BY LEVEL:生成连续行号,配合拆分函数实现一行转多行;PRIOR SYS_GUID() IS NOT NULL是为了避免Oracle处理多行拆分时出现循环引用问题。
如果你的数据不是固定某一行需要倒序,而是要根据input_name的顺序动态调整值的顺序,只需要修改最后一部分的排序逻辑即可,比如按input_name的元素位置倒序来聚合对应的值。
内容的提问来源于stack exchange,提问作者Rahmat
相关产品推荐
相关产品推荐

