StarRocks array_min 数组最小值函数:语法、示例与源码级实现解析

发布时间:2026/9/17 22:55:50
StarRocks array_min 数组最小值函数:语法、示例与源码级实现解析 StarRocks array_min 数组最小值函数语法、示例与源码级实现解析【免费下载链接】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_min是 StarRocks 提供的数组ARRAY聚合函数之一用于返回数组内全部元素中的最小值可作用于数值、日期时间与字符串等多种元素类型。本文以官方文档 array_min 为骨架完整讲解语法与可运行示例并结合 BE 端表达式引擎源码array_functions.tpp、array_functions.h与单元测试array_functions_test.cpp深入剖析其 NULL 语义、类型支持与线性扫描实现原理帮助你既会用、又知其所以然。函数概述与语义array_min的作用非常直观对传入 ARRAY 中的所有元素求最小值并返回。例如array_min([113, 11, 12])返回11。它属于 StarRocks 数组函数族array-functions与array_max求最大值、array_sum求和、array_avg求均值同属数组算术/极值类函数。在实际业务中常与unnest展开、array_map变换等函数配合用于对每行中嵌套的数组列做按行级的极值统计例如求每个用户历史订单金额数组的最低消费、每台设备延迟数组的最小延迟等。语法array_min(array(type))参数说明array(type)待求最小值的数组其元素类型为type从调用链看函数入参只接受 1 个数组列BE 端process函数中有DCHECK_EQ(1, columns.size())的强校验返回值与元素类型保持一致——即数组元素是什么类型最小值就是什么类型。返回值的类型与支持范围从源码结构看array_min是模板化实现函数模板ArrayArithmetic::array_minElementType以ResultType ElementType调用统一的process流水线即返回类型与数组元素类型相同不会发生类型提升。元素类型覆盖范围可以从单元测试中得到印证array_functions_test.cpp 中对以下类型均有测试用例整型TINYINT、INT、BIGINT、LARGEINT布尔型BOOLEAN浮点 / 高精度FLOAT、DOUBLE以及DECIMAL含DECIMALV2、DECIMAL128实现中会按上下文返回列的 precision/scale 创建结果列日期时间DATE、DATETIME字符串VARCHAR等字符串类型走lt_is_string分支初始值取第一个非 NULL 元素而非类型极值使用示例以下示例完整来自官方文档可直接在mysql客户端中运行验证。数值数组mysql select array_min([113, 11, 12]); ------------------------ | array_min([113,11,12]) | ------------------------ | 11 | ------------------------浮点数组mysql select array_min([11.33, 11.11, 12.324]); --------------------------------- | array_min([11.33,11.11,12.324]) | --------------------------------- | 11.11 | ---------------------------------日期时间数组mysql select array_min([cast(2020-02-25 11:35:17 as datetime), cast(2019-08-25 17:07:10 as datetime), cast(2025-08-25 17:07:10 as datetime)]); -------------------------------------------------------------------------------------------------------------------------------------- | array_min([CAST(2020-02-25 11:35:17 AS DATETIME),CAST(2019-08-25 17:07:10 AS DATETIME),CAST(2025-08-25 17:07:10 AS DATETIME)]) | -------------------------------------------------------------------------------------------------------------------------------------- | 2019-08-25 17:07:10 | --------------------------------------------------------------------------------------------------------------------------------------可以看出DATETIME数组同样按时间先后比较返回最早最小的时间点。对表列中的数组求最小值上述示例是常量数组实际更常见的是对表中 ARRAY 列逐行求最小值此时array_min天然按行处理逐行返回结果CREATE TABLE user_orders ( user_id INT, amounts ARRAYDECIMAL(10,2) ) ENGINEOLAP DUPLICATE KEY(user_id) DISTRIBUTED BY HASH(user_id) BUCKETS 3; -- 求每位用户的最小订单金额 SELECT user_id, array_min(amounts) AS min_amount FROM user_orders;边界条件与 NULL 语义array_min对空数组与 NULL 的处理是最容易踩坑的地方。这些语义在 BE 源码与单元测试中均有明确实现与验证1. 空数组返回 NULL在 ArrayMinMax::process 中对每个数组首先计算array_size offsets[i1] - offsets[i]若array_size 0则直接写入默认值并标记 NULL。测试用例array_min_empty_arrayarray_functions_test.cpp验证了对INT、BOOLEAN、TINYINT等类型的空数组结果列对应位置均为 NULL。2. 数组本身为 NULL 返回 NULL若整列数组是 NULL 值结果同样为 NULL。测试用例array_min_nullable_arrayarray_functions_test.cpp覆盖了该场景。3. 元素为 NULL 时跳过不参与比较当数组中某个元素为 NULL 时比较循环会跳过该元素continue其余元素正常参与求最小值。测试用例array_min_has_null_elementarray_functions_test.cpp覆盖了BIGINT、LARGEINT、DATE、DATETIME、VARCHAR等含 NULL 元素的数组。4. 全部元素为 NULL 时返回 NULL如果数组中所有元素都为 NULL或数组为空没有任何可比较的有效值结果列为 NULL。5. 字符串类型的特殊初值逻辑对字符串类型无法用类型极值作为比较初值因此实现采用跳过头部 NULL取第一个非 NULL 元素作为初值再与后续元素逐一比较的策略若数组中不存在任何非 NULL 字符串则返回 NULL。源码级实现原理array_min的完整执行路径为入口ArrayFunctions::array_min 将调用委托给ArrayArithmetic::array_mintype类型分派ArrayArithmetic::array_min 以ResultType ElementType调用ArrayArithmetic::processElementType, ElementType, ArrayMinMaxtrue通用流水线ArrayArithmetic::process 负责解包常量列、剥离可空包装、取出offsets数组偏移与elements元素列再按元素列是否含 NULL编译期选择ArrayMinMax::process..., HasNulltrue/false两个实例化版本核心算法ArrayMinMax::process 逐数组扫描。其核心算法值得展开说明列式内存布局StarRocks 的 ARRAY 采用偏移列 元素列的列式布局每个数组通过offsets[i]与offsets[i1]界定其元素区间因此计算最小值时无需物化数组对象直接对连续内存区间做线性扫描单次扫描 O(n)对每个数组算法从初值出发遍历其全部元素每次比较result value决定是否更新整体为单次线性扫描无排序、无额外临时容器分配仅结果列需要 reserve 行数空间性能开销极低适合大批量行级计算模板化分支消除HasNull作为编译期模板参数使得元素列无 NULL的常见路径不产生任何空值判断指令进一步压榨执行性能isMin同样为模板参数与array_max共用同一套ArrayMinMax模板仅极值方向不同初始值选择数值/日期类型求最小值时初值取RunTimeTypeLimitsResultType::max_value()该类型的最大值保证任意有效元素都能顶掉初值array_max则相反初值取min_value()。与 array_max 的对照使用array_min与 array_max 在源码上是同一个模板类ArrayMinMax的两个实例化方向ArrayMinMaxtrue求最小、ArrayMinMaxfalse求最大。两者的语法、类型支持、NULL 语义完全对称唯一区别是比较方向-- 一列数组同时求极值常用于分析波动区间 SELECT user_id, array_min(amounts) AS min_amount, array_max(amounts) AS max_amount, array_max(amounts) - array_min(amounts) AS amount_span FROM user_orders;相关函数array_min常与以下数组函数组合使用形成完整的数据分析能力array_max求数组最大值与array_min对称array_sum / array_avg对数组元素求和 / 求均值三者同属ArrayArithmetic体系共享process通用流水线array_length即cardinality获取数组长度可用于在计算前判断空数组array_sort对数组排序后取首元素也可得到最小值但排序为 O(n log n)在仅需极值时array_min的线性扫描明显更优unnest将数组展开为多行与array_min分别对应行内聚合与行间聚合两种数据处理视角。测试验证StarRocks 对array_min的语义有系统性的单测保障集中在 be/test/exprs/array_functions_test.cpp测试用例覆盖场景array_min_empty_arrayL2368空数组返回 NULL覆盖 INT / BOOLEAN / TINYINTarray_min_no_nullL2665无 NULL 元素的普通数组求最小值array_min_has_null_elementL2829数组中含 NULL 元素时跳过该元素array_min_nullable_arrayL3057数组本身为 NULL / 可空数组的场景这些用例从 BE 表达式执行层直接调用ArrayFunctions::array_minTYPE_XXX验证了从入口到列式算法的完整行为是上述 NULL 语义与类型支持结论的直接证据。小结array_min虽是一个小而美的数组函数但背后体现了 StarRocks 列式执行引擎的典型设计模板化的类型分派、编译期分支消除、基于偏移列的单次线性扫描以及严谨的 NULL 语义。掌握其语法、示例与边界行为即可在 SQL 中放心地对 ARRAY 列做行级最小值统计并理解它与array_max、array_sum共享的底层实现框架。说明文中函数行为、类型支持与 NULL 语义均以当前仓库的官方文档 array_min.md、BE 源码与单元测试为准实际使用时请匹配你所部署的 StarRocks 版本对应的行为。【免费下载链接】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),仅供参考