ClickHouse如何实现类似MySQL group_concat的有序分组拼接功能
问题原因
你之前的写法存在两个核心问题:
- 外层
ORDER BY input_time作用于GROUP BY之后的最终结果集,无法控制groupArray内部的元素排序,ClickHouse默认不保证聚合函数内部的元素顺序,因此会出现顺序混乱的问题。 - groupArray不会自行生成重复值,你遇到的多余重复值大概率是原始表中存在对应重复行,或是之前的查询有额外关联操作导致行膨胀,可以先统计对应值的行数确认是否为业务真实数据。
解决方案
你需要的按key分组、同组按input_time升序拼接name、保留真实重复值的需求,可以用以下两种写法实现:
方案1:聚合内指定排序(推荐,性能更优)
ClickHouse支持在聚合函数内部直接指定排序规则,控制groupArray的元素顺序,再用arrayStringConcat将数组拼接为逗号分隔的字符串:
SELECT key, arrayStringConcat(groupArray(name ORDER BY input_time ASC), ', ') AS name FROM fruits GROUP BY key
如果存在同key下input_time相同的行,可以在ORDER BY后补充其他唯一排序字段,保证拼接顺序的确定性。
方案2:预排序后聚合(兼容低版本ClickHouse)
如果你的ClickHouse版本不支持聚合内ORDER BY语法,可以先通过子查询对全表按input_time升序排序,再做分组聚合,groupArray会保留输入行的顺序:
SELECT key, arrayStringConcat(groupArray(name), ', ') AS name FROM ( SELECT key, name, input_time FROM fruits ORDER BY input_time ASC ) t GROUP BY key
内容的提问来源于stack exchange,提问作者user16535642
相关产品推荐
相关产品推荐

