ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

StarRocks 日期时间函数详解:minute() 提取分钟数

StarRocks 日期时间函数详解:minute() 提取分钟数 StarRocks 日期时间函数详解minute() 提取分钟数【免费下载链接】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本文以 StarRocks 内置日期时间函数minute()为核心系统讲解其语法、参数约束、返回值语义与典型使用场景并结合开源仓库中 BE存储引擎向量化实现与 FE前端常量折叠逻辑从源码层面解释该函数的执行原理。读完本文你将掌握minute()的完整用法能够将其用于按分钟粒度的分组统计、时间字段的分钟提取与报表加工等实战场景。minute()是 StarRocks 提供的最基础的日期时间提取类函数之一用于从DATE或DATETIME类型的时间值中取出分钟部分。它的姊妹函数包括hour()、second()三者共同覆盖了时分秒的时间分量提取需求。本文对应官方文档minute。函数签名与语法minute()的完整语法如下INT MINUTE(DATETIME|DATE date)该函数接收一个date参数并返回其分钟数返回值为INT类型取值范围为0到59。参数约束官方文档明确规定date参数必须是DATE或DATETIME类型。这一点在 StarRocks 的 FE 侧同样有对应的类型约束检查。如果你传入其他类型如字符串字面量StarRocks 会尝试按日期时间语义进行隐式转换若传入无法解析的值则会报错。从源码结构看FE 侧的 ScalarOperatorFunctions.java 为minute注册了两种常量折叠重载ConstantFunction.List(list { ConstantFunction(name minute, argTypes {DATETIME}, returnType TINYINT), ConstantFunction(name minute, argTypes {DATE}, returnType TINYINT) }) public static ConstantOperator minute(ConstantOperator value) { return ConstantOperator.createTinyInt((byte) value.getDatetime().getMinute()); }值得注意的是当输入为常量时FE 优化器会在查询编译阶段直接计算出结果并返回TINYINT类型而当输入为列时运行时求值BE 侧实现则按TYPE_DATETIME输入返回TYPE_INT结果详见下文底层实现原理。返回值语义返回分钟数范围0–59分钟值取自该时间在一天中的位置与日期、时区无关同一时刻的分钟部分不受时区设置影响因为时区转换发生在时间值本身的计算层面对于DATE类型输入其隐含时间为00:00:00因此minute()恒返回0。使用示例基础示例官方示例在 MySQL 客户端中执行MySQL select minute(2018-12-31 23:59:59); ----------------------------- |minute(2018-12-31 23:59:59)| ----------------------------- | 59 | -----------------------------该示例取自官方文档展示了在一天最后一分钟23:59:59时提取到的分钟值为59。边界值示例由于分钟部分取值固定为0–59可以通过以下语句验证边界行为-- 分钟最小边界0 分 SELECT minute(2024-01-01 10:00:30); -- 返回 0 -- 分钟最大边界59 分 SELECT minute(2024-01-01 10:59:30); -- 返回 59 -- DATE 类型输入隐含 00:00:00分钟恒为 0 SELECT minute(2024-01-01); -- 返回 0 -- 结合 hour()、second() 完整提取时分秒 SELECT hour(2024-01-01 10:35:47), -- 返回 10 minute(2024-01-01 10:35:47), -- 返回 35 second(2024-01-01 10:35:47); -- 返回 47实战按分钟粒度分组统计minute()最常见的实战场景是与GROUP BY配合对一天内的数据按分钟粒度聚合。例如统计某订单表在一天中各分钟内的订单量SELECT minute(create_time) AS minute_of_hour, COUNT(*) AS order_cnt FROM orders WHERE create_time 2024-06-01 00:00:00 AND create_time 2024-06-02 00:00:00 GROUP BY minute(create_time) ORDER BY minute_of_hour;若需要更细粒度的分钟级时间窗口跨小时连续可以结合DATE_FORMAT或TIMESLICE将时间按分钟切分再叠加minute()做展示层处理。底层实现原理BE 侧向量化一元函数实现minute()在 BE 侧的实现在 be/src/exprs/time_functions.cpp// minute of the hour DEFINE_UNARY_FN_WITH_IMPL(minuteImpl, v) { int hour1, mintue1, second1, usec1; v.to_time(hour1, mintue1, second1, usec1); return mintue1; } DEFINE_TIME_UNARY_FN(minute, TYPE_DATETIME, TYPE_INT);其中DEFINE_TIME_UNARY_FN宏time_functions.cpp将实现包装为向量化严格一元函数#define DEFINE_TIME_UNARY_FN(NAME, TYPE, RESULT_TYPE) \ StatusOrColumnPtr TimeFunctions::NAME(FunctionContext* context, const starrocks::Columns columns) { \ return VectorizedStrictUnaryFunctionNAME##Impl::evaluateTYPE, RESULT_TYPE(VECTORIZED_FN_ARGS(0)); \ }这意味着minute()对整列数据以批量、向量化的方式执行每次调用处理一个 Column 块充分借助 StarRocks 的 SIMD 向量化执行引擎性能远优于逐行解释执行。函数声明位于 be/src/exprs/time_functions.h/** * Get minute of the hour * param: [datetime] * return IntColumn minute of the hour: */ DEFINE_VECTORIZED_FN(minute);此外源码中还定义了minuteV2变体time_functions.cpp返回TYPE_TINYINT类型用于内存占用更紧凑的内部计算场景。FE 侧常量折叠优化当minute()的参数是字面常量例如minute(2018-12-31 23:59:59)时StarRocks FE 的优化器会在规划阶段直接调用 ScalarOperatorFunctions.java 中的常量求值逻辑把表达式预先折叠为常量59从而避免在 BE 端产生任何运行时开销。这也是官方示例能直接在 MySQL 客户端秒回的原因之一。测试用例验证BE 侧对应的单元测试位于 be/test/exprs/time_functions_test.cppTEST_F(TimeFunctionsTest, minuteTest) { auto tc TimestampColumn::create(); tc-append(TimestampValue::create(2020, 1, 1, 21, 22, 1)); tc-append(TimestampValue::create(2020, 2, 2, 14, 17, 1)); tc-append(TimestampValue::create(2020, 3, 6, 11, 54, 1)); tc-append(TimestampValue::create(2020, 4, 8, 9, 13, 1)); tc-append(TimestampValue::create(2020, 5, 9, 8, 8, 1)); tc-append(TimestampValue::create(2020, 11, 3, 23, 41, 1)); int days[] {22, 17, 54, 13, 8, 41}; ... ColumnPtr result TimeFunctions::minute(_utils-get_fn_ctx(), columns).value(); ... for (size_t i 0; i std::size(days); i) { ASSERT_EQ(days[i], year_days-get_data()[i]); } }该测试覆盖了多个时间点如21:22:01 → 22、14:17:01 → 17、23:41:01 → 41验证了分钟提取的正确性可作为深入阅读与二次开发时的参考基线。相关函数与联动使用在 StarRocks 的日期时间函数家族中与minute()紧密相关的函数包括函数作用源码位置hour()提取小时0–23time_functions.cppsecond()提取秒0–59time_functions.cppminutes_add()/minutes_sub()对时间按分钟加减time_functions.cppminutes_diff()计算两个时间的分钟差time_functions.cppdatetime_trunc(minute, ...)截断到分钟粒度time_functions.cpptime_slice(..., minute, ...)按分钟切分时间窗口time_functions.cpp在 FE 侧TimeUnitUtilsTimeUnitUtils.java统一定义了MINUTE时间单位常量供date_trunc、time_slice、minutes_diff等函数共用保证分钟这一时间单位在整条 SQL 编译链路中的语义一致。使用注意事项类型要求参数必须可解析为DATE或DATETIME。若向minute()传入无法解析的字符串会触发类型转换错误传入NULL时结果返回NULL。返回值范围恒为0–59的整数不会出现进位或跨小时行为——分钟提取是纯粹的字段截取操作。DATE 类型特例DATE类型不携带时间信息隐含00:00:00因此minute(date_col)恒为0若需提取时间分量请确保列类型为DATETIME。性能提示minute()是向量化严格一元函数无状态、无 I/O在百万行级别列上的批量求值开销极低配合谓词下推与常量折叠可以放心用于大表查询。总结minute()是 StarRocks 中最简单、最高效的日期时间提取函数之一语法简洁、语义明确对DATE/DATETIME类型入参返回0–59的分钟整数。本文不仅覆盖了官方文档的全部示例与语法说明还从 time_functions.cpp 的向量化宏实现、ScalarOperatorFunctions.java 的常量折叠注册以及 time_functions_test.cpp 的单元测试三个维度完整还原了该函数从 SQL 语法到执行引擎的全链路实现。掌握它是深入理解 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),仅供参考
返回列表