首页 / 聚合
COLLECT_SET 去重聚合为数组
COLLECT_SET 把一组值去重后聚合成数组。MaxCompute、Doris、Hive 和 Spark 同名可用,Hologres、StarRocks 和 Flink 要改写为 ARRAY_AGG(DISTINCT ...)。各引擎都不保证数组元素的顺序。
各引擎写法
| 引擎 | 支持 | 写法 | 说明 | 依据 |
|---|---|---|---|---|
| MaxCompute | 支持 | COLLECT_SET(colname) |
返回去重后的数组,值为 NULL 的行不参与计算。 | 官方文档 |
| Hologres | 需改写 | ARRAY_AGG(DISTINCT expression) |
没有 COLLECT_SET,用 ARRAY_AGG。不支持 JSON、JSONB、INTERVAL 和数组等类型。 | 官方文档 |
| StarRocks | 需改写 | ARRAY_AGG(DISTINCT col) |
在 StarRocks 文档中搜索不到 COLLECT_SET。ARRAY_AGG_DISTINCT 是 ARRAY_AGG(DISTINCT) 的别名。ARRAY_AGG 会保留 NULL。 | 官方文档 |
| Doris | 支持 | COLLECT_SET(expr[, max_size]) |
别名 GROUP_UNIQ_ARRAY。会过滤 NULL,max_size 限制数组长度。 | 官方文档 |
| Hive | 支持 | collect_set(col) |
返回去重后的 array。 | 官方文档 |
| Spark SQL | 支持 | collect_set(expr) |
Spark 2.0.0 起提供。文档注明结果顺序取决于 shuffle 后的行序,是不确定的。 | 官方文档 |
| Flink SQL | 需改写 | ARRAY_AGG(DISTINCT expression) |
也可以用 COLLECT(DISTINCT expression),返回的是 MULTISET 而不是数组。 | 官方文档 |
迁移注意事项
- 元素顺序不固定。同一份数据跑两次,数组顺序可能不同,直接拿数组做比较或拼接成字符串做关联会出错。需要稳定顺序时用 SORT_ARRAY 包一层。
- NULL 的处理不同:MaxCompute、Doris 会丢弃 NULL,StarRocks 的 ARRAY_AGG 会保留 NULL。迁移到 StarRocks 后数组里可能多出 NULL 元素。
- Doris 的 max_size 截断时保留哪些元素,文档没有说明,不要依赖它取“前 N 个”。
示例
每个门店售卖过的商品类目
SELECT store_id, COLLECT_SET(category) FROM sales GROUP BY store_id;SELECT store_id, ARRAY_AGG(DISTINCT category) FROM sales GROUP BY store_id;SELECT store_id, ARRAY_AGG(DISTINCT category) FROM sales GROUP BY store_id;SELECT store_id, ARRAY_AGG(DISTINCT category) FROM sales GROUP BY store_id;