ClickHouse能否实现查询字段返回对象数组类型结果?
ClickHouse返回多列组成的对象数组实现方案
可以实现该需求,核心思路是先将单行的多列打包为单个复合类型元素,再用groupArray对复合元素做聚合即可,常用实现方式如下:
方式1:返回元组数组(性能最优,适合内部逻辑处理)
直接用tuple()函数将需要的列打包为匿名元组,再传入groupArray聚合,示例如下:-- 示例表结构:user_action(user_id UInt32, action_type String, action_time Datetime) SELECT user_id, groupArray(tuple(action_type, action_time)) AS action_list FROM user_action GROUP BY user_id返回结果的
action_list字段类型为Array(Tuple(String, Datetime)),可通过下标访问对应字段,例如action_list[1].2即可取到第一个数组元素的action_time值。方式2:返回带字段名的KV对象数组(适合直接返回给前端使用)
若需要每个元素都为带字段名的结构化对象,可使用JSON_OBJECT函数(21.8+版本支持)将行数据转为JSON对象后聚合,示例如下:SELECT user_id, groupArray( JSON_OBJECT( 'action_type', action_type, 'action_time', action_time ) ) AS action_list FROM user_action GROUP BY user_id低版本不支持
JSON_OBJECT的场景下,也可以用map()函数替代,返回Array(Map(String, String))类型的结果,同样可以通过字段名访问值。方式3:返回强类型结构化数组(22.3+版本支持)
如果需要严格的类型校验,可搭配STRUCT类型定义结构化元素,示例如下:SELECT user_id, groupArray( cast( (action_type, action_time) as Struct<'action_type': String, 'action_time': Datetime> ) ) AS action_list FROM user_action GROUP BY user_id
注意事项
- 如需对聚合元素做条件过滤,可直接替换
groupArray为groupArrayIf,用法和常规条件聚合函数一致 - 大数据量场景下建议限制数组长度,避免单条数据内存占用过高,可搭配
groupArray(limit N, 字段)语法或者groupArraySample函数控制元素数量
内容的提问来源于stack exchange,提问作者YayoUK
相关产品推荐
相关产品推荐

