StarRocks cardinality() 函数详解:获取数组与 Map 元素个数的权威指南

发布时间:2026/9/17 17:50:20

StarRocks cardinality() 函数详解:获取数组与 Map 元素个数的权威指南 StarRocks cardinality() 函数详解获取数组与 Map 元素个数的权威指南【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrockscardinality()是 StarRocks 中用于返回数组ARRAY元素个数的内置函数也是array_length()的别名两者语义完全等价。本指南围绕该函数展开覆盖语法、参数、NULL 语义、嵌套数组行为、源码级实现原理、函数注册机制与单元测试验证并给出可直接复制的 SQL 示例帮助你准确使用它在多维分析、实时分析和即席查询场景中计算数组维度信息。函数概述返回数组元素个数cardinality()接收一个数组作为输入返回该数组的元素个数结果类型为INT。它是array_length()的别名从 StarRocks v3.0 起开始支持。核心语义要点统计元素个数返回数组中元素的个数而不是数组在存储上的字节大小NULL 输入返回 NULL如果输入参数本身为 NULL结果同样为 NULLNULL 元素计入长度数组内部的 NULL 元素会计入长度不会被跳过结果为 INT返回值类型为INT无论数组元素是什么类型。该函数在 StarRocks 官方文档中的定义见 cardinality.md其别名文档为 array_length.md。语法与参数cardinality()的函数签名如下INT cardinality(any_array)参数说明any_array需要获取元素个数的 ARRAY 值可以是任意元素类型的数组也支持嵌套数组多维数组参数说明any_array可以是字面量数组、数组类型的列也可以是返回数组类型的表达式支持任意元素类型INT、VARCHAR、DECIMAL 等以及嵌套的 ARRAYARRAY... 多维数组数组参数还可以来自array_agg()等聚合函数构造的结果或来自unnest表函数展开后的中间结果。返回值与 NULL 语义cardinality()的返回值类型为INT其 NULL 语义遵循以下规则输入情况返回值说明普通数组[1,2,3]3返回元素个数含 NULL 元素的数组[1,2,3,null]4NULL 元素会计入长度空数组[]0空数组长度为 0NULL 输入NULL输入为 NULL 时结果也是 NULL值得注意的区别是数组元素为 NULL 与整个数组为 NULL 是两种不同的情况。[NULL]是一个包含一个 NULL 元素的数组其长度为 1而数组本身为 NULL即该数组列取值为 NULL时cardinality()返回 NULL。这一点可以从仓库中的单元测试得到印证详见下文测试验证一节。使用示例以下示例均可在 StarRocks 的 MySQL 客户端中直接执行。一维数组统计元素个数mysql select cardinality([1,2,3]); ----------------------- | cardinality([1,2,3]) | ----------------------- | 3 | ----------------------- 1 row in set (0.00 sec)NULL 元素计入长度mysql select cardinality([1,2,3,null]); ------------------------------ | cardinality([1, 2, 3, NULL]) | ------------------------------ | 4 | ------------------------------可以看到数组中的 NULL 元素被计入总数结果为 4。嵌套数组只统计第一层元素个数mysql select cardinality([[1,2], [3,4]]); ----------------------------- | cardinality([[1,2],[3,4]]) | ----------------------------- | 2 | ----------------------------- 1 row in set (0.01 sec)cardinality()只统计最外层的元素个数因此[[1,2], [3,4]]的结果是 2外层有两个子数组而不是 4。若需要统计内层子数组的元素个数可配合unnest表函数先展开再计算。作用于表列统计每行数组字段的长度CREATE TABLE user_tags ( user_id INT, tags ARRAYVARCHAR(20) ) DUPLICATE KEY(user_id) DISTRIBUTED BY HASH(user_id) BUCKETS 4 PROPERTIES (replication_num 1); INSERT INTO user_tags VALUES (1, [star, rock]), (2, [olap]), (3, NULL), (4, []); SELECT user_id, tags, cardinality(tags) AS tag_cnt FROM user_tags ORDER BY user_id;user_idtagstag_cnt1[star,rock]22[olap]13NULLNULL4[]0该示例同时展示了四种典型情况普通数组返回元素个数、单元素数组返回 1、数组为 NULL 时返回 NULL、空数组返回 0。与 array_length() 完全等价由于cardinality()是array_length()的别名以下两条语句返回完全一致的结果SELECT cardinality([10, 20, 30]); -- 3 SELECT array_length([10, 20, 30]); -- 3与 array_length() 的关系cardinality()与array_length()是互为别名的关系cardinality()文档中明确标注它是array_length()的别名array_length()文档中同样标注它有一个别名cardinality()见 array_length.md。两个函数在功能上没有任何差异你可以根据团队编码习惯或 SQL 可读性选择任意一个。它们在关键字索引keyword中也相互关联CARDINALITY, ARRAY_LENGTH, ARRAY。源码级实现原理核心实现基于 ArrayColumn 的 offsets 计算cardinality在 StarRocks BE后端中统一映射到向量化函数ArrayFunctions::array_length其实现位于 array_functions.cpp。核心逻辑如下StatusOrColumnPtr ArrayFunctions::array_length([[maybe_unused]] FunctionContext* context, const Columns columns) { DCHECK_EQ(1, columns.size()); RETURN_IF_COLUMNS_ONLY_NULL(columns); const size_t num_rows columns[0]-size(); const auto* col_array down_castconst ArrayColumn*(ColumnHelper::get_data_column(columns[0].get())); const auto arr_offsets col_array-offsets().immutable_data(); if (columns[0]-is_constant()) { // 常量列直接复用偏移量差构造 ConstColumn auto col_result Int32Column::create(); col_result-append(arr_offsets.data()[1]); auto const_column ConstColumn::create(std::move(col_result), num_rows); return const_column; } else { // 普通列逐行计算 offsets[i1] - offsets[i] int32_t* p col_result-get_data().data(); for (size_t i 0; i num_rows; i) { p[i] arr_offsets[i 1] - arr_offsets[i]; } if (arg0-has_null()) { // 复制 NULL 标记保持输入可空列的 null bitmap 不被修改 return NullableColumn::create(std::move(col_result), std::move(null_column)); } else { return col_result; } } }实现要点解读基于偏移量差计算StarRocks 的数组列以ArrayColumn表示内部通过offsetsUInt32Column记录每个数组在元素列中的起始位置。第i个数组的长度就是offsets[i1] - offsets[i]因此函数整体是 O(1) 的向量化逐行运算无需遍历数组元素本身常量列优化当输入是常量列如字面量[1,2,3]在列式执行中被物化为常量时只需计算一次长度然后构造ConstColumn广播到所有行避免重复计算NULL 语义的传递当输入列存在 NULL 时函数会复制输入的 null bitmap 到结果列从而保证输入为 NULL输出为 NULL的语义同时从源码注释和测试可以看出该函数不会修改输入可空列的 null bitmap返回值类型结果写入Int32Column对应 SQL 层面的INT返回类型。函数声明ArrayFunctions::array_length的向量化函数声明位于 array_functions.hDEFINE_VECTORIZED_FN(array_length);注册机制cardinality 同时支持 ARRAY 与 MAPStarRocks 的内置函数通过构建脚本 functions.py 集中注册。搜索该文件可以发现cardinality与array_length的注册记录# L1073: array_length 主注册支持 ANY_ARRAY返回 INT [150000, array_length, True, False, INT, [ANY_ARRAY], ArrayFunctions::array_length], # L1575-L1576: cardinality 是重载函数同时支持 MAP 与 ARRAY [170100, cardinality, True, False, INT, [ANY_MAP], MapFunctions::map_size], [170101, cardinality, True, False, INT, [ANY_ARRAY], ArrayFunctions::array_length],从这个注册信息可以得出两个重要结论cardinality是array_length的别名两者都指向同一个后端实现ArrayFunctions::array_length注册表150000与170101完全对应cardinality还是一个重载函数除了数组它还接受ANY_MAP类型的参数并返回 Map 的键值对个数此时映射到MapFunctions::map_size实现位于 map_functions.cpp同样通过 offsets 差分offsets[i1] - offsets[i]计算与数组的实现思路一致。也就是说SQL 中cardinality(...)会根据实参类型自动分发数组走ArrayFunctions::array_lengthMap 走MapFunctions::map_size。而array_length只接受数组。这也解释了为什么cardinality一词在数据库语境中常被用来表示集合的基数元素个数。测试验证StarRocks 为array_length/cardinality提供了完整的单元测试位于 array_functions_test.cpp 的TEST_F(ArrayFunctionsTest, array_length)用例中。测试覆盖了以下关键场景空数组[]→ 0NULL 输入数组本身为 NULL → 返回 NULL含 NULL 元素的数组[NULL]→ 1NULL 元素计入长度一维数值数组[1]→ 1[1,2]→ 2字符串数组[a]→ 1[a,b]→ 2嵌套数组[[NULL]]→ 1[[]]→ 1[[],[]]→ 2[[1],[2],[3]]→ 3不可变性测试断言array_length不会修改输入可空列的 null bitmap常量列优化路径测试构造ConstColumn输入验证常量列分支的正确性4 个元素的数组被广播为 3 行每行结果均为 4。此外array_length还被广泛用于 Lambda 高阶函数中例如 lambda_array_expr_test.cpp 展示了在array_map(b - array_length(a) b, a)这类嵌套 Lambda 表达式中作为公共子表达式提取的场景。典型应用场景cardinality()在实践中通常与其他数组函数配合使用1. 过滤空数组或 NULL 数组SELECT user_id, tags FROM user_tags WHERE cardinality(tags) 0;2. 与 array_agg() 结合统计分组后的元素个数SELECT dept_id, array_agg(emp_name) AS emp_names, cardinality(array_agg(emp_name)) AS emp_cnt FROM employees GROUP BY dept_id;3. 与 unnset/unnest 配合处理嵌套数组-- 统计多维数组中每个子数组的长度 SELECT t.sub_arr, cardinality(t.sub_arr) AS sub_len FROM (SELECT [[1,2],[3,4,5]] AS arr) a, UNNEST(a.arr) AS t(sub_arr);4. 在高阶函数中度量数组规模array_length/cardinality经常出现在array_map、array_filter、array_sort的 Lambda 表达式中用于依据数组长度进行映射、过滤或排序。注意事项与限制版本要求cardinality()从 StarRocks v3.0 起支持只统计第一层对于多维数组只返回最外层元素个数不会递归统计NULL 语义区分元素 NULL 计入长度数组本身为 NULL 时结果为 NULL返回类型始终返回INT不会溢出数组长度受 StarRocks 数组列 offsets 的UINT32表示约束与 array_length 等价两者可在 SQL 中互换使用对 Map 的扩展cardinality()对ANY_MAP参数同样有效返回键值对个数这是其与array_length的一个区别array_length仅支持数组。参考文档与源码函数文档cardinality.md、array_length.md后端实现array_functions.cpp、array_functions.hMap 扩展实现map_functions.cpp函数注册表functions.py、functions.py单元测试array_functions_test.cpp、lambda_array_expr_test.cpp【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/17 17:45:20

PostgreSQL报错分层排查:FATAL与ERROR实战

1. 报错先分层:PostgreSQL的错误信息其实是有规律的用了这么多年 PostgreSQL,我发现一个挺有意思的现象:新手看到ERROR就慌,老手看到ERROR先看它是哪一层报出来的。PostgreSQL 的报错看着吓人,动不动一整段英文往上刷&…

2026/9/17 17:45:20

swarms 框架 OneToOne 指南:双智能体一对一对话模式详解

swarms 框架 OneToOne 指南:双智能体一对一对话模式详解 【免费下载链接】swarms The Enterprise-Grade Multi-Agent Orchestration Framework. Website: https://swarms.ai 项目地址: https://gitcode.com/GitHub_Trending/swar/swarms 本文围绕 swarms 多智…

2026/9/17 23:41:06

智慧体育场馆信息化整体建设:架构设计与系统集成实践

简介:面向智慧体育场馆建设与升级的完整信息化解决方案(49页演示文稿),适合体育场馆运营方、弱电与音视频系统集成商、赛事保障及方案设计人员,重点解决场馆音视频系统分散、赛事指挥调度不畅、多系统融合难等实际问题…

2026/9/17 23:41:06

VS Code 中 JS/TS 语言服务反复崩溃?Volar 插件的排查与修复指南

下午正写着一个 Vue 3 组件,VS Code 右下角突然弹出一条红色错误:**“JS/TS 语言服务已立即崩溃 5 次。不会重新启动该服务。这可能是由以下其中一个扩展提供的插件引起的: Vue.volar。”**那一瞬间,语法高亮还在,但自动补全、跳转…

2026/9/17 23:41:06

Spring Context深度解析:从Bean生命周期到三级缓存与依赖注入

1. Spring Context到底是个什么东西每次看到讲Spring的教程,很多同学第一反应都是“又是Bean生命周期那一套,背完就忘”。但今天这篇我想换一个角度,从Spring Context本身入手,把这个框架最核心的容器概念讲透。Spring Context&am…

2026/9/17 23:41:06

Android Studio 无法运行项目?run配置丢失根源与修复步骤

从 GitHub 上拉下一个项目,或者拿起自己三个月前写的工程,双击项目文件夹,Android Studio 加载了老半天,右下角进度条终于消失,你点右上角的 Run 按钮,却发现它是灰的;打开Run > Edit Config…

2026/9/17 23:36:06

10机39节点电力系统Matlab/Simulink仿真实战:从潮流计算到暂态稳定

做电力系统研究的人,应该都绕不开10机39节点这个经典算例,尤其是要用Matlab和Simulink做电力系统仿真的时候,它几乎是验证控制算法、分析暂态稳定的默认试验场。我最近完整地做了一遍这个项目,从数据准备、潮流计算、Simulink模型…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码