news 2026/10/10 4:02:01

MySQL日期加减函数DATE_ADD与DATE_SUB完全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL日期加减函数DATE_ADD与DATE_SUB完全解析

作为一名常年跟MySQL打交道的老开发,我几乎每天都要跟日期时间打交道。统计、报表、定时任务、过期判断,凡是涉及时间窗口的计算,基本绕不开DATE_ADD和DATE_SUB这两个函数。很多人嘴上说会用,真到写SQL的时候连参数顺序都能搞反,或者被INTERVAL的语法折磨到怀疑人生。这篇文章我干脆一次性讲透,从语法、参数、场景到高频坑,全给你梳理清楚,看完你也能写出干净的日期时间计算SQL。

这两个函数说白了就是在指定日期时间上增减一段间隔,返回一个新的日期时间。DATE_ADD是加上间隔,DATE_SUB是减去间隔。它们的价值在于:你不需要自己写一堆繁琐的年月日加减逻辑,也不用担心月末、闰年这些边界情况,数据库引擎会帮你处理好。比如你要算“三个月前的今天”,直接DATE_SUB(NOW(), INTERVAL 3 MONTH)就完事。如果手动写DATE_ADD(NOW(), INTERVAL -3 MONTH),其实结果也是一样的,因为负间隔就是减法,两者可以互换使用。这就是函数设计的对称之处,理解了这一点,你就能在不同风格的SQL代码里自由切换。

适用人群很明确:刚学SQL的新手、做数据分析的同事、后端开发写报表接口的老手,以及那些需要在业务代码里拼时间条件的工程师。把这俩函数用熟,你写时间范围查询会省掉一大半力气,还不容易出错。

1. 函数全貌:语法、参数与返回类型

1.1 标准语法结构全解

先看官方标准语法:

DATE_ADD(date, INTERVAL expr unit) DATE_SUB(date, INTERVAL expr unit)

两个函数的参数结构完全一致,第一个参数是基准日期或日期时间,第二个参数是间隔表达式。间隔表达式由两部分组成:一个数值expr和一个单位unit。数值可以是整数、负数、小数甚至表达式,单位决定了这个数值代表的是天、小时、月还是年。

举个具体例子:

SELECT DATE_ADD('2025-05-20', INTERVAL 10 DAY); -- 结果:2025-05-30 SELECT DATE_SUB('2025-05-20', INTERVAL 10 DAY); -- 结果:2025-05-10

10 DAY就是“10天”这个间隔。DATE_ADD往未来走,DATE_SUB往过去走。从功能上讲,DATE_ADD('2025-05-20', INTERVAL -10 DAY)等价于DATE_SUB('2025-05-20', INTERVAL 10 DAY)。知道了这个等价关系,代码风格就能统一,团队协作时也少一些理解偏差。

1.2 关键参数类型说明

date参数可以接受多种数据类型:DATE、DATETIME、TIMESTAMP都可以,甚至合法的日期时间字符串也行。传入字符串时,MySQL会自动完成隐式转换。但我要提醒一句:能用时间类型就用时间类型,千万别指望字符串格式五花八门时还能正确解析。比如'2025/05/20'这种斜杠格式MySQL勉强认识,'2025.05.20'这种就属于自找麻烦。

返回类型遵循一个规则:如果date参数是DATE类型且间隔单位不涉及小时、分钟、秒,返回的就是DATE;一旦间隔包含了HOUR、MINUTE、SECOND等时间部分,返回类型自动变成DATETIME。DATETIME类型参与计算时,结果也保持DATETIME。实战里很多人踩过这个坑:以为返回的一定是DATE,结果输出带着00:00:00,跟前端格式匹配不上,就在那排查半天。

expr参数还可以写成浮点数,比如INTERVAL 1.5 HOUR表示一个半小时。MySQL 会把这个数换算成整数时间单位存储,1.5 HOUR实际就是90 MINUTE。这个特性在计算平均耗时、增量时间时挺有用,但要注意换算后的精度情况,太刁钻的小数可能导致不可预期结果,能用整数尽量用整数。

1.3 函数的对称性与等价写法

DATE_ADD和DATE_SUB是对称存在的。真实开发里,我见过有人永远只写DATE_SUB,因为他的业务场景全是往前推时间;也见过有人只写DATE_ADD,需要用负数间隔来兼做减法。这两种风格都行,但从可读性角度,我推荐:

  • 明确语义:加时间用DATE_ADD,减时间用DATE_SUB,别混用负号
  • 维护方便:如果后头同事要改逻辑,一眼就能看出是加法还是减法

再补充一个冷知识:DATE_ADD和DATE_SUB其实是 MySQL 中ADDDATE、SUBDATE的“完整版”。后两者有简写形式,比如ADDDATE(date, INTERVAL 1 DAY)等价于DATE_ADD(date, INTERVAL 1 DAY),而且ADDDATE(date, 5)这种只写天数间隔的写法只属于ADDDATE,DATE_ADD不支持省略INTERVAL关键字。所以如果你看到同事代码里写ADDDATE(create_time, 30),别惊讶,这是合法的,不过就是省略了单位,默认按天算,稍微有点隐晦。

2. 间隔表达式 INTERVAL 的深入拆解

2.1 所有单位类型详解

INTERVAL支持的单位非常全,这是它强大之处。官方文档列出的单位我整理成一张表,方便你查阅:

单位含义示例
MICROSECOND微秒INTERVAL 5000 MICROSECOND
SECOND秒INTERVAL 30 SECOND
MINUTE分钟INTERVAL 15 MINUTE
HOUR小时INTERVAL 8 HOUR
DAY天INTERVAL 30 DAY
WEEK周INTERVAL 2 WEEK
MONTH月INTERVAL 6 MONTH
QUARTER季度INTERVAL 1 QUARTER
YEAR年INTERVAL 2 YEAR
SECOND_MICROSECOND秒+微秒组合INTERVAL '10.5' SECOND_MICROSECOND
MINUTE_MICROSECOND分+秒+微秒组合INTERVAL '10:20.5' MINUTE_MICROSECOND
MINUTE_SECOND分+秒组合INTERVAL '10:20' MINUTE_SECOND
HOUR_MICROSECOND时+分+秒+微秒组合INTERVAL '10:20:30.5' HOUR_MICROSECOND
HOUR_SECOND时+分+秒组合INTERVAL '10:20:30' HOUR_SECOND
HOUR_MINUTE时+分组合INTERVAL '10:20' HOUR_MINUTE
DAY_MICROSECOND天+时+分+秒+微秒组合INTERVAL '1 10:20:30.5' DAY_MICROSECOND
DAY_SECOND天+时+分+秒组合INTERVAL '1 10:20:30' DAY_SECOND
DAY_MINUTE天+时+分组合INTERVAL '1 10:20' DAY_MINUTE
DAY_HOUR天+时组合INTERVAL '1 10' DAY_HOUR
YEAR_MONTH年+月组合INTERVAL '2-3' YEAR_MONTH

看到DAY_HOUR这种组合,可能有人已经有点晕了。它的格式规则其实很简单:前面是较大单位,后面是较小单位,中间用什么分隔符取决于具体单位。DAY_HOUR用空格,YEAR_MONTH用横杠,HOUR_MINUTE用冒号。组合单位在排期计算、任务调度窗口这种需要精确到秒的场合会用到,平时不常见,但面试的时候偶尔会抽出来问,知道有这么个东西心里不慌。

2.2 组合单位写法与注意事项

组合单位最容易出错的是格式,我挑两个高频的写一下:

-- 增加 1 天 10 小时 20 分钟 30 秒 SELECT DATE_ADD('2025-05-20 12:00:00', INTERVAL '1 10:20:30' DAY_SECOND); -- 结果:2025-05-21 22:20:30 -- 增加 2 年 3 个月 SELECT DATE_ADD('2025-05-20', INTERVAL '2-3' YEAR_MONTH); -- 结果:2027-08-20

注意组合单位的引号不能丢。INTERVAL 1 10:20:30 DAY_SECOND这种写法绝对是错的,数值和组合单位之间必须用字符串包起来。就这个引号问题,我见过不止一个同事在代码评审时被指出来。

再提醒一点:不能叠着写。有人想加“1年2个月”居然写成INTERVAL 1 YEAR + 2 MONTH,这直接语法报错。正确的做法用YEAR_MONTH组合,或者干脆分两步写两个函数嵌套,虽然丑点但不会出错:

SELECT DATE_ADD(DATE_ADD('2025-05-20', INTERVAL 1 YEAR), INTERVAL 2 MONTH); -- 结果:2026-07-20

在我的实际开发经验里,组合单位用的频率远低于单一单位。99%的业务场景拆成两步加更清晰,组合单位主要图一个“一步到位”,但代价是可读性下降。你需要在代码可读性和简洁性之间做个取舍,没有绝对答案,团队统一风格就好。

2.3 INTERVAL 的关键行为细节

间隔表达式的数值支持正负数,这是设计上非常优雅的一点。负数会让加法变减法,正数让减法变加法。所以理论上你可以只记一个函数,DATE_ADD(date, INTERVAL -x unit)就能覆盖所有场景。

对于MONTH、YEAR这类大单位,MySQL 在运算时有一个非常容易忽略的行为:结果会尽量保持基准日期的“日”不变,但如果目标月份没有这个日子,会取目标月份的最后一天。比如:

SELECT DATE_ADD('2025-01-31', INTERVAL 1 MONTH); -- 结果:2025-02-28 SELECT DATE_ADD('2024-01-31', INTERVAL 1 MONTH); -- 结果:2024-02-29(闰年)

1月31日加一个月,2月没有31日,MySQL自动给你落到2月的最后一天。这个行为让很多人又爱又恨:爱的是它不会报错,恨的是结果可能跟你的直觉不一样。如果你预期的是“跟1月31日对应的2月31日”,在票务、订阅扣费等业务里这就需要特殊处理。我的建议是:凡是涉及月末日期加减的,先算清楚业务期望值,再决定要不要用 DATE_ADD 直接算。比如客户订阅月底到期,你要算下个月的扣费日,最好先用LAST_DAY()拿到当月最后一天,再基于最后一天加减,否则很容易出现连续几个月的扣费日漂移。

3. 高频实战:DATE_ADD 与 DATE_SUB 的典型应用

3.1 近N天/周/月数据统计

这是最常见的场景。你要统计近7天的订单量,直接这么写:

SELECT COUNT(*) FROM orders WHERE order_time >= DATE_SUB(NOW(), INTERVAL 7 DAY);

注意,order_time是DATETIME类型,DATE_SUB(NOW(), INTERVAL 7 DAY)返回的也是DATETIME,类型匹配不会出幺蛾子。但如果你用CURDATE()(只返回日期部分),那就要小心边界。NOW()带时间,CURDATE()不带时间,混用在>=和<条件时可能会把当天零点到当前时刻的数据漏掉或重复统计,这个等到第4节配合索引一起细讲。

月初到现在的数据,可以用DATE_SUB配合DATE_FORMAT拼一个月的起点,也可以用DATE_ADD直接算下个月的起点:

-- 从本月1号到现在的数据 SELECT COUNT(*) FROM orders WHERE order_time >= DATE_FORMAT(NOW(), '%Y-%m-01') AND order_time < DATE_ADD(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 1 MONTH);

第二个条件里的DATE_ADD(CURDATE(), INTERVAL 1 MONTH)看起来是在当前日期上加一个月,实际因为先做了DATE_FORMAT取月初,所以得到的是下个月1号零点。配合<号,就能精确圈定整个月的范围,不漏一秒。这个写法的好处是不用关心月份天数,2月、闰年都自动处理。

3.2 时间戳与日期的双栖转换

日期时间字符串可以直接参与运算,UNIX_TIMESTAMP()出来的整数用FROM_UNIXTIME()转回时间类型后同样可以参与计算。有些人在代码里用DATE_ADD(FROM_UNIXTIME(create_time), INTERVAL 1 DAY)来算过期时间,我建议还是在SQL查询层尽量保持类型一致,别老在函数之间来回横跳。如果确实存的是整型时间戳,直接在应用层做加减更清爽,把整型加减算完再转回去:

-- 伪代码,假设 create_ts 是整型时间戳 SELECT FROM_UNIXTIME(create_ts + 86400) AS expire_time FROM user_orders;

为什么说不要过度依赖 SQL 函数?因为一旦你钻进了DATE_ADD(FROM_UNIXTIME(...))这种写法,索引基本就废了。只要字段被函数包住,MySQL 大概率不会走索引。这个在第5节详细说,这里先留个印象。

3.3 会员到期、优惠券过期的判定

电商系统的会员到期时间计算,典型做法是开卡时存一个到期时间,或者每次操作时用缓存时间加延长天数。假设用户开通了30天会员,开卡时间存在created_at,那到期时间可以用:

SELECT DATE_ADD(created_at, INTERVAL 30 DAY) AS expire_at FROM memberships WHERE user_id = 123;

优惠券同理,一张券从valid_from到valid_until,判断是否可用:

SELECT coupon_id, title FROM coupons WHERE DATE_SUB(NOW(), INTERVAL 0 DAY) BETWEEN valid_from AND valid_until;

这个例子有点故意绕弯子。实际你只需要把NOW()跟两个字段比较就完了,不需要套函数。但文科生也能看出来,DATE_SUB(NOW(), INTERVAL 0 DAY)就是NOW()本身,写出来只是为了演示语法上的灵活性,没实际意义。真实项目里千万别这么写,纯粹增加阅读负担。

3.4 定时任务与周期性提醒

后端写定时任务扫描超时未支付的订单:

UPDATE orders SET status = 'cancelled' WHERE status = 'pending' AND created_at < DATE_SUB(NOW(), INTERVAL 30 MINUTE);

这里的语义非常清晰:超过30分钟未支付的订单自动取消。DATE_SUB(NOW(), INTERVAL 30 MINUTE)算出一个时间点,凡是created_at早于这个点的,都触发超时。

如果你希望任务在凌晨执行,比如每天1点统计前一天的数据:

SELECT COUNT(*) FROM orders WHERE order_time >= DATE_SUB(DATE_FORMAT(NOW(), '%Y-%m-%d'), INTERVAL 1 DAY) AND order_time < DATE_FORMAT(NOW(), '%Y-%m-%d');

这种写法把CURDATE()的概念显式化:当天零点往前推一天,就是昨天零点;当天零点就是范围的右边界,左闭右开。整个统计范围恰好覆盖昨天全天。

4. 常见报错与认知误区实录

4.1 语法报错:INTERVAL 位置写错

报错现象:Syntax error near 'INTERVAL'或Incorrect parameters in the call to DATE_ADD。

这种错十有八九是把参数顺序搞反了。有人会写成:

-- 错误写法 SELECT DATE_ADD(INTERVAL 1 DAY, '2025-05-20');

正确顺序一定是基准日期在前,INTERVAL 表达式在后。这跟直觉“加多少时间”有点拧,但函数设计就是这么定的,记一次就不容易忘了。

实用公式:永远先写DATE_ADD(,然后敲基准日期/字段,再敲, INTERVAL,再敲数值和单位,右括号收尾。顺序别动,基本不会错。

4.2 字符串日期格式导致的隐式转换问题

MySQL的隐式转换有时很智能,有时很坑。比如:

-- 这种写法能跑,但结果可能不对 SELECT DATE_ADD('2025-13-45', INTERVAL 1 DAY);

如果字符串严重不合法,MySQL直接返回NULL并在日志里留下 warning,而不会帮你修正。最诡异的是有些非法日期 MySQL 也能解析,比如'2025-02-30'在某些版本里能转换成三月初的值,这种行为会直接污染统计结果。所以从应用层传参过来时,尽量保证传的是DATETIME/TIMESTAMP类型,把字符串到日期的转换放在显式的STR_TO_DATE或CAST上:

SELECT DATE_ADD(CAST('2025-05-20 12:00:00' AS DATETIME), INTERVAL 1 DAY);

4.3 月末日期的“神奇漂移”

前面说过加一个月可能落到下月最后一天。这不算报错,但很容易造成业务逻辑偏差。比如每个月的30号要生成下月账单日,你直接用DATE_ADD('2025-01-30', INTERVAL 1 MONTH)得到2025-02-28,然后下一次基于2月28日再算,得出3月28日,账期就一路漂移了。要是本意是“每月月底出账”,那就应该基于LAST_DAY(CURRENT_DATE)来算,而不是基于上个月的账单日。处理这类逻辑时,要问一句:加一个月到底是“日历上对应的日期”,还是“下一个月的月底”。两种业务语义完全不同,用错就出大事。

4.4 时区问题:存 UTC 还是存本地时间

NOW()跟CURRENT_TIMESTAMP都返回当前会话时区的时间。如果 MySQL 服务器的time_zone参数设置不对,DATE_SUB(NOW(), INTERVAL 1 DAY)算出的时间点跟真实世界差了8小时,统计出来的数据自然不准。

排查思路:

  • 执行SELECT NOW(), CURRENT_TIMESTAMP, @@session.time_zone, @@global.time_zone;
  • 如果是SYSTEM,看操作系统时区是否正常
  • 如果业务需要跨时区,建议统一存储 UTC 时间,展示时再转本地时间,绝不在数据库里做时区加减后再存

这点看着跟函数本身没直接关系,但只要你用DATE_ADD/DATE_SUB跟NOW()配合,时区就是绕不开的坑。我排查过不少线上数据差8小时的事故,最后定位全是时区配置问题而不是函数用错。

5. 性能影响与替代方案权衡

5.1 函数包裹字段导致索引失效

这条是性能层面最重要的提醒。只要你把索引字段包进函数,MySQL 大概率放弃走索引。比如:

-- 索引失效风险写 SELECT * FROM orders WHERE DATE_ADD(order_time, INTERVAL 1 DAY) > NOW();

这个条件把order_time包在了DATE_ADD里,优化器很难把它转换成范围扫描。更好的写法是把计算挪到常量侧:

SELECT * FROM orders WHERE order_time > DATE_SUB(NOW(), INTERVAL 1 DAY);

这么写,order_time是裸字段,DATE_SUB(NOW(), INTERVAL 1 DAY)是一个确定的常量(执行时算一次),B+树索引就能正常走范围扫描。这个原则不只是针对 DATE_ADD / DATE_SUB,而是所有 SQL 函数都适用。判断标准很简单:哪个字段被函数包住,哪个字段就难受。

5.2 NOW()、CURDATE()、CURRENT_TIMESTAMP 的取舍

同类函数过多也会让人困惑。说下区别:

  • NOW():返回DATETIME,包含当前日期和时间,精度到秒(可带小数)
  • CURDATE():只返回当前日期,DATE类型
  • CURRENT_TIMESTAMP:跟NOW()基本等价,在DEFAULT子句里更常用

在日期时间加减中,如果你只关心天级别统计,用CURDATE()可以避免时间部分带来的边界问题:

-- 查昨天的数据(不含今天零点) SELECT * FROM logs WHERE log_date >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND log_date < CURDATE();

而NOW()适合精确到秒的场景。混用两者时,特别注意log_date是否包含时间部分。如果log_date是DATE类型,用DATE_SUB(CURDATE(), INTERVAL 1 DAY)就够了;如果是DATETIME,用NOW()并调整边界会更严谨。

5.3 与 TIMESTAMPDIFF / DATEDIFF 的功能边界

DATE_ADD/DATE_SUB解决的是“一个时间点加一段间隔得到另一个时间点”,而TIMESTAMPDIFF/DATEDIFF解决的是“两个时间点之间的间隔有多大”。一个是正向运算,一个是反向运算,正好互补:

-- 计算两个时间相差多少天 SELECT DATEDIFF('2025-05-20', '2025-05-10'); -- 结果:10 -- 计算两个时间相差多少个月 SELECT TIMESTAMPDIFF(MONTH, '2025-01-15', '2025-06-10'); -- 结果:4

TIMESTAMPDIFF按整单位截断,不满一个月的部分直接舍弃,这是它的语义。如果你用DATE_ADD('2025-01-15', INTERVAL 5 MONTH)再反向验证,得到2025-06-15,然后用TIMESTAMPDIFF(MONTH, '2025-01-15', '2025-06-15')就会得到 5。所以两者组合使用可以完成互逆逻辑的验证。写复杂统计SQL时可以这两组函数来回验证逻辑,能发现不少隐蔽偏差。

5.4 大规模数据下的替代策略

如果表数据量到了千万级,频繁用DATE_SUB(NOW(), INTERVAL N DAY)做过滤也没什么问题,只要索引列是裸的。但如果你在同一个查询里对多个时间字段做一堆加减,比如DATE_ADD(update_time, INTERVAL 2 HOUR) > DATE_SUB(NOW(), INTERVAL 1 DAY),这种写法既复杂又容易让优化器懵掉。更稳妥的做法是:把边界值算好再传入 SQL 查询。比如在 Java 或 Python 代码里先算好startTime和endTime两个变量,SQL 里直接WHERE update_time BETWEEN ? AND ?。好处很多:SQL 逻辑简单、索引友好、参数化查询防注入、业务规则在代码层可测试。SQL 函数适合快速实现、临时分析、报表脚本;应用层计算适合核心链路、性能敏感的接口。两者不矛盾,关键看场景。

6. 实操干货:写日期时间加减SQL的九条心得

6.1 统一用裸字段接常量

所有查询条件里,把函数尽量用在常量侧,索引字段保持“裸奔”。这是查询性能的第一原则。

6.2 能用 CURDATE 别用 NOW 的场景别搞反

如果统计维度是天,边界就用CURDATE()配DATE_SUB;如果要精确到秒,才用NOW()。写之前问一句:这个条件到底需不需要时间部分?需要是几点几分几秒吗?不需要就果断CURDATE()。

6.3 嵌套函数不要超过两层

嵌套超过两层,人脑基本就转不过来了。遇到复杂日期计算,宁可拆成两个查询或者在应用层算好,也别写个五层嵌套的“祖传SQL”。后头维护的人会骂娘的。

6.4 月末日期先想清楚业务语义

涉及会员月卡、账单周期时,用LAST_DAY()显式处理月末,不要依赖DATE_ADD的“自动落到月末”行为。这个行为在不同业务下可能是feature也可能是bug,别让它偷偷决定你的业务规则。

6.5 检查 INTERVAL 的引号与格式

组合单位必须用引号包起来。INTERVAL '2-3' YEAR_MONTH是对的,INTERVAL 2-3 YEAR_MONTH是错的。这个错误提示不一定直观,报错时会让你看半天语法。

6.6 排查返回 NULL 的常见原因

DATE_ADD返回NULL大概率是参数非法。优先检查:

  • 第一个参数是不是合法日期时间
  • 数值是不是超出单位允许范围
  • 有没有在函数里传NULL值(只要传了 NULL,结果一定是 NULL)

6.7 用 TIMESTAMPDIFF 反向验证逻辑

写完一串加减后,用TIMESTAMPDIFF或DATEDIFF验证一下结果是否符合预期。比如要“推后一个月”,算完再用TIMESTAMPDIFF(MONTH, 原日期, 新日期)看是不是1。这种逆向验证习惯能帮你省下不少线上bug排查时间。

6.8 不要在循环里逐行用函数

ORM 里循环几十次,每次执行一条带DATE_SUB的查询,这种写法性能会很差。日期范围计算适合一次性生成范围,比如在SQL里生成连续日期序列:

SELECT DATE_ADD('2025-05-01', INTERVAL seq.seq DAY) AS day FROM ( SELECT ones.num + tens.num * 10 + hundreds.num * 100 AS seq FROM ... -- 拼一个数字序列 ) seq;

这种“连续日期序列生成”在报表补齐缺失日期时相当好用,一次调用生成一整张日历表。前提是数字序列辅助表要提前建好,别临时写大段笛卡尔积,性能还是可控的。

6.9 使用前先确定 MySQL 版本

不同 MySQL 版本对日期函数的实现细节略有差异,特别是INTERVAL组合单位的微秒精度和时区行为。线上生产环境升级后,最好把核心日期计算SQL过一遍回归测试,防的是函数行为变化导致的隐性数据错误。尤其是从 5.7 升到 8.0 的时候,TIMESTAMP的存储行为和时区处理都有调整,牵连着DATE_ADD/DATE_SUB的表现。


这个函数组合我实际用下来最大的体会是:它们不复杂,但边界情况极其丰富。真正让你翻车的往往不是函数本身,而是你以为自己理解了“加一个月”是什么意思。把业务语义想清楚,再把日期计算交给数据库,这套配合能让你少掉很多头发。

最后分享一个写这类 SQL 时养成的习惯:凡是涉及日期时间范围的条件,我都会额外写一行注释,标明这个条件的业务含义、期望边界和实测结果。比如order_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)下面注释一行“统计从当前时刻往前推7天(含),不含未来数据”。等到三个月后你回来看这段SQL,或者同事临时接手你的报表任务,这一行注释比什么都管用。日期函数本身写起来很快,真正值钱的是你沉淀下来的这些边界判断和业务约定。

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

ip_ip.net 201907.zip离线IP库解析:从格式识别到二分查询实战

简介&#xff1a;一份ipip.net于2019年7月发布的全国最新IP地址库数据包&#xff0c;面向网络管理员、安全工程师、数据分析师与电信运维人员&#xff0c;主要解决IP归属地精准查询、恶意地址识别、访问者地域分布统计和网络规划参考等需求。压缩包内共1个SQL文件&#xff0c;大…

作者头像 李华
网站建设 2026/10/10 4:01:05

从0到1构建可运行Agent系统:架构、工具调用与工程实践

1. 为什么"会聊天"和"会干活"是两码事很多人第一次接触Agent这个概念时&#xff0c;脑子里浮现的画面是科幻电影里那种能陪你聊天、帮你查天气的语音助手。但真正上手做项目之后你会发现&#xff0c;Agent的核心价值根本不在于"聊得好"&#xff…

作者头像 李华
网站建设 2026/10/10 4:00:43

多层结构瞬态响应仿真全解析:建模、时间步长与求解实战

1. 项目概述1.1 核心需求解析先说清楚这是个什么东西吧。你在做过程序仿真、设备热设计&#xff0c;或者单纯在学CFD类软件&#xff0c;迟早会碰上传热学仿真里的瞬态响应问题。普通稳态工况只告诉你系统最终会稳定在什么温度&#xff0c;但不回答“到底多久才能到”“中间会不…

作者头像 李华
网站建设 2026/10/10 4:00:26

低功耗手持设备电源管理实战:PCA9422与PIC32MX764F128L协同设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 4:00:11

12GB显卡如何跑125B大模型?Strata分层调度与量化压缩实战

1. 这个标题到底在讲什么第一次看到“12GB显卡跑125B参数模型”这个说法&#xff0c;我的第一反应是&#xff1a;这不可能。按照常规认知&#xff0c;125B参数的模型&#xff0c;光是权重加载&#xff0c;就算用4bit量化&#xff0c;也得占掉60GB以上的显存&#xff0c;12GB连零…

作者头像 李华
网站建设 2026/10/10 3:59:38

用AI搭建被动收入系统:从选品到自动交付的完整框架

1. 从“用工具”到“建系统”&#xff1a;被动收入的思维切换很多人第一次看到“用AI做被动收入”这个说法&#xff0c;脑子里蹦出来的画面大概是&#xff1a;打开对话框&#xff0c;敲几行字&#xff0c;然后钱就自动流进来了。我一开始也这么想过&#xff0c;甚至真的试过连续…

作者头像 李华