在Oracle数据库的实际开发场景中,我们常常需要将同一个分组下的多行数据合并成一行,并且用逗号作为分隔符展示,wm_concat函数就是实现这个需求的高效工具,它能够快速完成列转行的操作。

wm_concat函数基本说明
wm_concat是Oracle提供的一个非官方内置聚合函数,主要作用是将多个行的列值拼接成一个字符串,默认使用逗号作为分隔符。它的基本语法格式如下:
-- 基本语法 WM_CONCAT(列名) -- 结合分组使用 SELECT 分组列, WM_CONCAT(拼接列) FROM 表名 GROUP BY 分组列;
需要注意的是,wm_concat函数在不同Oracle版本中的表现可能存在差异,部分新版本中已经不再官方支持该函数,使用时需要确认数据库环境是否兼容。
wm_concat列转行逗号分隔示例
假设我们有一张员工部门表emp_dept,结构如下:
| dept_id | emp_name |
|---|---|
| 10 | 张三 |
| 10 | 李四 |
| 20 | 王五 |
| 20 | 赵六 |
| 20 | 钱七 |
现在需要按照部门id分组,将每个部门的员工姓名用逗号分隔拼接成一行,使用wm_concat函数的查询语句如下:
SELECT dept_id, WM_CONCAT(emp_name) AS emp_list FROM emp_dept GROUP BY dept_id ORDER BY dept_id;
执行上述语句后,会得到如下结果:
| dept_id | emp_list |
|---|---|
| 10 | 张三,李四 |
| 20 | 王五,赵六,钱七 |
wm_concat使用注意事项
- wm_concat函数返回的是CLOB类型,如果拼接的内容长度较短,可以通过
TO_CHAR函数转换为字符串类型,避免后续处理出现类型不匹配的问题。 - 由于该函数是非官方函数,在Oracle 12c及更高版本中可能被移除,如果需要兼容更高版本,可以考虑使用官方支持的
LISTAGG函数替代,LISTAGG函数的用法类似,且支持自定义分隔符。 - 当拼接的内容中存在NULL值时,wm_concat函数会自动忽略NULL值,不会将其计入拼接结果中。
替代方案LISTAGG函数示例
如果需要更稳定的官方支持,可以使用LISTAGG函数实现相同的列转行逗号分隔需求,示例代码如下:
-- LISTAGG实现列转行逗号分隔
SELECT dept_id,
LISTAGG(emp_name, ',') WITHIN GROUP (ORDER BY emp_name) AS emp_list
FROM emp_dept
GROUP BY dept_id
ORDER BY dept_id;
上述语句中,LISTAGG的第一个参数是要拼接的列,第二个参数是分隔符,WITHIN GROUP (ORDER BY 列名)用来指定拼接时的排序规则,执行结果和wm_concat的结果一致。