news 2026/9/20 6:34:18

StarRocks array_sum 数组求和函数详解:语法、类型映射与 NULL 语义

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
StarRocks array_sum 数组求和函数详解:语法、类型映射与 NULL 语义

StarRocks array_sum 数组求和函数详解:语法、类型映射与 NULL 语义

【免费下载链接】starrocksThe world's 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

array_sum()是 StarRocks 内置的数组聚合函数,用于对数组中的全部元素求和,返回单个数值。本文围绕 array_sum 官方文档 展开,结合 BE 端源码实现与单元测试,系统讲解其语法、支持的数据类型、返回值类型映射、NULL 处理语义,以及如何与array_map()配合使用 lambda 表达式完成"先变换、再求和"的复合计算,帮助你写出类型安全、行为可预期的高效查询。

功能概述

array_sum(array)接收一个数组参数,返回该数组中所有元素的累加和。它适用于 StarRocks 中的 Array 类型列,典型场景包括:

  • 对一维数组列(如标签权重、评分序列、交易明细列表)直接求和;
  • 结合 lambda 表达式对元素先做变换(平方、缩放、条件映射)后再求和,例如计算向量的平方和。

从 StarRocks 2.5 版本开始,array_sum()支持以 lambda 表达式作为参数,但它不能直接与 lambda 表达式协同工作,必须作用于array_map()转换后的结果之上,即array_sum(lambda_function, arr1, arr2...)等价于array_sum(array_map(lambda_function, arr1, arr2...))

语法

array_sum(array(type)) array_sum(lambda_function, arr1, arr2...) = array_sum(array_map(lambda_function, arr1, arr2...))

两种形式分别对应:

形式说明
array_sum(array(type))直接对数组array中的元素求和,最常见的基本用法
array_sum(array_map(lambda_function, arr1, arr2...))先用 lambda 函数对多个数组做逐元素变换,再对结果求和;array_sum(lambda_function, arr1, arr2...)仅是这种写法的简写

参数说明

  • array(type):要求和的数组。数组元素支持以下数据类型:BOOLEANTINYINTSMALLINTINTBIGINTLARGEINTFLOATDOUBLEDECIMALV2
  • lambda_function:用于计算目标数组的 lambda 表达式,配合array_map()使用。例如x -> x * x表示对每个元素取平方后再交由array_sum()求和。

返回值类型:由元素类型推导

array_sum()的返回类型并非与输入类型完全一致,而是按照"防止溢出、保证精度"的原则向上提升。从 BE 端实现 array_functions.tpp 的ArrayArithmetic::array_sum可以看出类型映射关系:

数组元素类型求和返回类型说明
BOOLEAN/TINYINT/SMALLINT/INTBIGINT小整数类型统一提升为 64 位整数,避免累加溢出
BIGINTBIGINT保持原类型
LARGEINTLARGEINT128 位大整数
FLOAT/DOUBLEDOUBLE浮点类型统一提升为双精度
DECIMALV2DECIMALV2保持十进制高精度语义
其他DECIMAL类型DECIMAL128提升为 128 位十进制,扩大精度与取值范围

因此文档中"Returns a numeric value(返回一个数值)"的表述,其确切含义是:返回值类型是上表中与元素类型匹配的数值类型,具体类型取决于数组元素类型。这种提升策略意味着对小整数数组求和时无需担心中间结果溢出,而对浮点数组求和则统一到DOUBLE精度。

使用示例

直接对数组求和(无 lambda)

对整数数组求和:

mysql> select array_sum([11, 11, 12]); +-----------------------+ | array_sum([11,11,12]) | +-----------------------+ | 34 | +-----------------------+

对浮点数数组求和:

mysql> select array_sum([11.33, 11.11, 12.324]); +---------------------------------+ | array_sum([11.33,11.11,12.324]) | +---------------------------------+ | 34.764 | +---------------------------------+

结合 lambda 表达式求和

先对[1, 2, 3]的每个元素求平方(得到[1, 4, 9]),再求和:

-- Multiply [1,2,3] by [1,2,3] and sum the elements. select array_sum(array_map(x->x*x,[1,2,3])); +---------------------------------------------+ | array_sum(array_map(x -> x * x, [1, 2, 3])) | +---------------------------------------------+ | 14 | +---------------------------------------------+

该写法等价于array_sum(x -> x * x, [1, 2, 3]),两者结果一致,均返回14。关于array_map()的完整语法与 lambda 书写规范,可参见 array_map 函数文档。

NULL 与空数组语义

理解array_sum()对 NULL 的处理,对正确解读结果至关重要。从 array_functions.tpp 中ArraySumAvg的实现逻辑,以及 array_functions_test.cpp 的单元测试,可以归纳出以下规则:

  1. 数组本身为 NULL:直接返回 NULL(实现中当数组列仅有 NULL 时原样返回,见 array_functions.tpp)。
  2. 空数组:返回 NULL。测试用例array_sum_empty_array明确验证了空数组[]的求和结果为 NULL(对应 array_functions_test.cpp)。
  3. 数组中存在 NULL 元素:NULL 元素会被跳过,不参与累加;只要数组中存在至少一个非 NULL 元素,就返回其余元素的累加和。对应测试用例array_sum_has_null_element(见 array_functions_test.cpp)。
  4. 全 NULL 或空数组等无有效数据的情形:结果为 NULL(实现中has_data为 false 时写入默认值并置 NULL 标记,见 array_functions.tpp)。

换言之,array_sum()对 NULL 元素的语义与标准 SQL 聚合函数SUM一致:忽略 NULL、仅累加有效值,但没有有效值时结果为 NULL,而不是 0。这在处理稀疏数组(如含缺失值的评分序列)时尤为关键,可避免将缺失值误当作 0 参与求和。

底层实现原理

array_sum()在 BE 端经由 array_functions.h 注册到ArrayArithmetic::array_sum,其核心流程为:

  1. 类型分派:根据模板参数ElementType在编译期确定结果类型(BIGINT/LARGEINT/DOUBLE/DECIMALV2/DECIMAL128),不支持的输入类型会直接报错(见 array_functions.tpp)。
  2. 按行遍历:通过数组列的 offsets 定位每个数组的起止下标,逐元素累加(见 array_functions.tpp);若元素列带 NULL 标记,则跳过 NULL 元素。
  3. 结果写出:将每行的累加和写入结果列,无有效数据的行写入 NULL。整个计算对 Array 列逐行独立完成,天然支持向量化批处理,适合在海量 Array 行上做列级聚合。

测试覆盖了空数组、含 NULL 元素、可空数组、无 NULL 元素等多种组合(array_functions_test.cpp),可作为理解边界行为的参考。

注意事项与最佳实践

  • 使用前确认元素类型array_sum()不支持 STRING、DATE、DATETIME 等非数值类型,也不支持 ARRAY 嵌套数组的直接求和;若需对嵌套数组求和外层和内层需分别处理。
  • 大数组注意数值范围:整数类型求和结果会自动提升(如INTBIGINT),但超大LARGEINT累加仍需留意是否超出表示范围。
  • NULL 不会当作 0:若业务上希望"缺失即 0",可先用array_map(x -> ifnull(x, 0), arr)之类的变换将 NULL 替换为 0,再调用array_sum()
  • 复合计算推荐 lambda 写法:需要先变换再求和时,使用array_sum(array_map(lambda, arr))或简写array_sum(lambda, arr),一次查询即可完成"逐元素变换 + 汇总",避免中间结果落地。

相关文档

  • array_sum 函数文档
  • array_map 函数文档
  • 实现与测试:array_functions.tpp、array_functions.h、array_functions_test.cpp

【免费下载链接】starrocksThe world's 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 5:10:26

PSO算法优化光伏MPPT:突破局部遮阴挑战

1. 新能源控制器中的MPPT挑战与机遇光伏发电系统在实际运行中常常面临局部遮阴的困扰,就像一片树林中总有几棵树会投下阴影。当光伏阵列部分区域被遮挡时,其功率-电压(P-V)特性曲线会出现多个峰值点,这给传统的最大功率点跟踪(MPPT)算法带来了…

作者头像 李华
网站建设 2026/9/20 7:16:02

AI时代企业核心生产力重构与开源策略升级

1. 项目概述:AI时代的生产力边界重构最近三年,我观察到企业技术战略正在经历一场静默革命。传统的外包与开源边界在生成式AI冲击下变得模糊不清——某电商平台将80%的客服代码交给AI生成,某金融公司用开源大模型替代了原本外包的智能投顾模块…

作者头像 李华
网站建设 2026/9/20 9:35:18

Notepad-- 文件对比功能实战:多版本差异比对的完整指南

Notepad-- 文件对比功能实战:多版本差异比对的完整指南 【免费下载链接】notepad-- 一个支持windows/linux/mac的文本编辑器,目标是做中国人自己的编辑器,来自中国。 项目地址: https://gitcode.com/GitHub_Trending/no/notepad-- 备份…

作者头像 李华
网站建设 2026/9/20 7:01:43

半导体物理基础与芯片设计关键技术解析

1. 芯片设计中的半导体物理基础半导体物理是芯片设计的根基,就像建筑需要坚实的地基一样。我从业十几年,见过太多工程师因为物理基础不扎实而在设计时走弯路。让我们从最基础的能带理论开始,聊聊这些看似抽象的概念如何直接影响芯片性能。1.1…

作者头像 李华
网站建设 2026/9/20 5:11:13

从零到贡献者:Folo社区协作全攻略

从零到贡献者:Folo社区协作全攻略 你是否曾想为开源项目贡献力量,却被复杂的协作流程吓退?本文将以Folo项目为例,带你一步步掌握从环境搭建到代码提交的完整流程,让你轻松成为社区贡献者。读完本文,你将能…

作者头像 李华