首页 / 聚合
WM_CONCAT 分组拼接字符串
WM_CONCAT 是 MaxCompute 的分组字符串拼接函数,分隔符写在前面。迁到其他引擎时要换函数名,并注意分隔符的位置:Hologres 用 STRING_AGG,StarRocks 和 Doris 用 GROUP_CONCAT,Flink 用 LISTAGG。
各引擎写法
| 引擎 | 支持 | 写法 | 说明 | 依据 |
|---|---|---|---|---|
| MaxCompute | 支持 | WM_CONCAT(separator, colname) |
分隔符必须是常量且写在前面。支持 DISTINCT 和 WITHIN GROUP (ORDER BY ...),值为 NULL 的行不参与计算。 | 官方文档 |
| Hologres | 需改写 | STRING_AGG(expression, delimiter) |
分隔符写在后面,只拼接非 NULL 值。 | 官方文档 |
| StarRocks | 需改写 | GROUP_CONCAT([DISTINCT] expr [ORDER BY ...] [SEPARATOR sep]) |
默认分隔符是逗号,跳过 NULL。结果长度受 group_concat_max_len 限制,默认 1,024 个字符,超出部分会被截断。 | 官方文档 |
| Doris | 需改写 | GROUP_CONCAT([DISTINCT] str[, sep] [ORDER BY ...]) |
分隔符是第二个参数,默认是逗号加空格。DISTINCT 与 ORDER BY 同时使用从 2.1.6 起支持。 | 官方文档 |
| Hive | 需改写 | concat_ws(',', collect_list(col)) |
函数手册中没有 WM_CONCAT,用 concat_ws 拼接 collect_list 的结果,顺序不固定。 | 官方文档 |
| Spark SQL | 需改写 | string_agg(expr[, delimiter]) WITHIN GROUP (ORDER BY ...) |
string_agg 和 listagg 从 Spark 4.0.0 起提供。更早的版本用 concat_ws(',', collect_list(expr))。 | 官方文档 |
| Flink SQL | 需改写 | LISTAGG(expression[, separator]) |
分隔符写在后面。 | 官方文档 |
迁移注意事项
- 分隔符的位置相反:WM_CONCAT 写在第一个参数,STRING_AGG、GROUP_CONCAT(Doris)和 LISTAGG 写在最后。直接替换函数名会把分隔符当成要拼接的值。
- StarRocks 的 GROUP_CONCAT 默认最多 1,024 个字符,超出部分不报错直接截断。长列表需要先调大 group_concat_max_len。
- 不写排序时,各引擎拼接的顺序都不固定。需要稳定结果时,MaxCompute 写 WITHIN GROUP (ORDER BY ...),StarRocks 和 Doris 在 GROUP_CONCAT 内写 ORDER BY。
- StarRocks 3.0.6 和 3.1.3 起,GROUP_CONCAT 必须用 SEPARATOR 关键字声明分隔符。
示例
按门店拼接员工姓名
SELECT store_id, WM_CONCAT(',', name) WITHIN GROUP (ORDER BY name) FROM staff GROUP BY store_id;SELECT store_id, STRING_AGG(name, ',') FROM staff GROUP BY store_id;SELECT store_id, GROUP_CONCAT(name ORDER BY name SEPARATOR ',') FROM staff GROUP BY store_id;SELECT store_id, GROUP_CONCAT(name, ',' ORDER BY name) FROM staff GROUP BY store_id;SELECT store_id, concat_ws(',', collect_list(name)) FROM staff GROUP BY store_id;SELECT store_id, LISTAGG(name, ',') FROM staff GROUP BY store_id;