StarRocks array_sum 数组求和函数详解:语法、类型映射与 NULL 语义 StarRocks array_sum 数组求和函数详解语法、类型映射与 NULL 语义【免费下载链接】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/starrocksarray_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)要求和的数组。数组元素支持以下数据类型BOOLEAN、TINYINT、SMALLINT、INT、BIGINT、LARGEINT、FLOAT、DOUBLE、DECIMALV2。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 的单元测试可以归纳出以下规则数组本身为 NULL直接返回 NULL实现中当数组列仅有 NULL 时原样返回见 array_functions.tpp。空数组返回 NULL。测试用例array_sum_empty_array明确验证了空数组[]的求和结果为 NULL对应 array_functions_test.cpp。数组中存在 NULL 元素NULL 元素会被跳过不参与累加只要数组中存在至少一个非 NULL 元素就返回其余元素的累加和。对应测试用例array_sum_has_null_element见 array_functions_test.cpp。全 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其核心流程为类型分派根据模板参数ElementType在编译期确定结果类型BIGINT/LARGEINT/DOUBLE/DECIMALV2/DECIMAL128不支持的输入类型会直接报错见 array_functions.tpp。按行遍历通过数组列的 offsets 定位每个数组的起止下标逐元素累加见 array_functions.tpp若元素列带 NULL 标记则跳过 NULL 元素。结果写出将每行的累加和写入结果列无有效数据的行写入 NULL。整个计算对 Array 列逐行独立完成天然支持向量化批处理适合在海量 Array 行上做列级聚合。测试覆盖了空数组、含 NULL 元素、可空数组、无 NULL 元素等多种组合array_functions_test.cpp可作为理解边界行为的参考。注意事项与最佳实践使用前确认元素类型array_sum()不支持 STRING、DATE、DATETIME 等非数值类型也不支持 ARRAY 嵌套数组的直接求和若需对嵌套数组求和外层和内层需分别处理。大数组注意数值范围整数类型求和结果会自动提升如INT→BIGINT但超大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 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),仅供参考