ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

StarRocks weeks_sub 函数详解:DATETIME 周数减法运算的原理与实战

2026/9/18 20:00:17 拓冰建站 浏览量
StarRocks weeks_sub 函数详解:DATETIME 周数减法运算的原理与实战 StarRocks weeks_sub 函数详解DATETIME 周数减法运算的原理与实战【免费下载链接】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/starrocksweeks_sub是 StarRocks 提供的日期时间函数用于从一个DATETIME值中减去指定周数是数据仓库中做周期回溯分析如环比、滚动窗口、周期报表的常用工具。本文将基于官方文档与仓库源码完整讲解其语法、参数约束、返回值规则、典型用法并深入其 BEBackend与 FEFrontend两侧的实现原理帮助你正确、高效地使用该函数。函数概览与语法weeks_sub的官方语法定义如下见 weeks_sub.mdDATETIME weeks_sub(DATETIME expr1, INT expr2);expr1原始日期必须为DATETIME类型expr2需要减去的周数必须为INT类型返回值类型DATETIME。从函数命名看它与weeks_add周数加法互为逆运算二者在 StarRocks 的日期时间函数族中是一组成对出现的接口。同族函数还包括years_add/years_sub、months_add/months_sub、days_add/days_sub、hours_add/hours_sub等可统一参考 date-time-functions 目录下的对应文档。参数详解expr1原始日期expr1必须是DATETIME类型的值。在 SQL 中直接书写字符串字面量如2022-12-22时StarRocks 会按照默认的日期时间格式将其隐式转换为DATETIME因此官方示例中可以直接传入字符串。如果传入的是DATE类型列建议先用CAST或str_to_date等函数转换为DATETIME后再参与运算以保证类型语义清晰。expr2周数expr2为INT类型表示要减去的周数。需要注意两点正数表示向过去回溯weeks_sub(ts, 2)表示将ts向前过去方向拨回 2 周负数等价于加周从底层实现看下文「实现原理」会展开减法是通过对时间值执行「加负数值」完成的因此weeks_sub(ts, -2)与weeks_add(ts, 2)效果一致。返回值与边界情况正常返回DATETIME类型的结果精确到秒时间部分保持与输入一致如果输入的日期不存在例如2022-02-29这类非法日期函数返回NULL传入NULL参数时返回NULL遵循标准 SQL 的 NULL 传播语义。使用示例官方示例原文档给出的基准示例可复制到 StarRocks 客户端直接执行select weeks_sub(2022-12-22,2); ---------------------------- | weeks_sub(2022-12-22, 2) | ---------------------------- | 2022-12-08 00:00:00 | ----------------------------从2022-12-22减去 2 周14 天得到2022-12-08 00:00:00。扩展实战示例结合周数与时间部分可以进行更精细的周期回溯-- 带时间部分的 DATETIME 回溯 SELECT weeks_sub(2022-12-22 14:30:00, 2); -- 2022-12-08 14:30:00 -- 用负数实现「减负 加」与 weeks_add 相互印证 SELECT weeks_sub(2022-12-20, -1); SELECT weeks_add(2022-12-20, 1); -- 两者结果一致均为 2022-12-27 -- 与当前时间结合做「4 周前」分析 SELECT weeks_sub(NOW(), 4); -- 配合表列做周期对比统计 4 周前的订单量 SELECT sum(case when dt weeks_sub(2022-12-22, 4) then amount else 0 end) AS this_period, sum(case when dt weeks_sub(2022-12-22, 4) then amount else 0 end) AS prev_period FROM orders;与加法版本对照可参考 weeks_add.md 中的weeks_add(2022-12-20, 2)示例两者语法完全对称便于记忆。底层实现原理BE 侧统一宏展开实现在存储引擎侧weeks_sub的向量化实现位于 time_functions.cpp。它并没有单独书写逻辑而是与weeks_add一起通过宏DEFINE_TIME_ADD_AND_SUB_FN(weeks, TimeUnit::WEEK)生成加法宏timestamp_addTimeUnit::WEEK(timestamp, count)减法宏timestamp_addTimeUnit::WEEK(timestamp, -count)即「减 n 周」被实现为「加上 -n 周」。这意味着减法天然支持负数参数且与加法共享同一套基于TimeUnit::WEEK的日历运算内核能够正确处理跨月、跨年如 12 月底减 4 周进入 11 月以及闰年等日历边界。该函数在 time_functions.h 中以DEFINE_VECTORIZED_FN(weeks_sub)注册为向量化函数可对整列数据批量执行获得良好的列式处理性能。FE 侧常量折叠与单调性标记在前端优化器中weeks_sub被注册为可常量折叠的函数定义于 ScalarOperatorFunctions.javaConstantFunction(name weeks_sub, argTypes {DATETIME, INT}, returnType DATETIME, isMonotonic true) public static ConstantOperator weeksSub(ConstantOperator date, ConstantOperator week) { return ConstantOperator.createDatetimeOrNull(date.getDatetime().minusWeeks(week.getInt())); }关键点isMonotonic true函数是单调的优化器可以利用该性质对涉及weeks_sub的谓词做范围推导如把weeks_sub(dt, 1) 2022-01-01改写为对dt的可索引范围从而提升查询性能常量折叠当expr1为常量时FE 会在执行前直接调用minusWeeks求出结果避免运行时开销该函数名同时在 FunctionSet.java 中登记参与全局函数解析。典型应用场景滚动周期报表以周为单位回溯历史数据如计算「本周 vs 四周前」的订单、活跃用户对比数据清理与归档按weeks_sub(create_time, N)圈定 N 周前的数据范围时间窗口计算与NOW()、CURRENT_TIMESTAMP组合动态生成如「近 4 周」「近 12 周」的分析窗口。小结weeks_sub语法简洁、语义直观是 StarRocks 中做周粒度时间回溯的标准函数。在使用时注意两点expr1保证为DATETIME语义、expr2为INT负数等价于做加法。理解其「减法即加负」的实现本质与 FE 侧的单调性优化可以帮助你在编写周期分析 SQL 时写出更高效、更可靠的查询。【免费下载链接】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),仅供参考