MySQL 日期加减函数详解
MySQL 日期加减函数详解
1. DATE_ADD 函数
基本语法
DATE_ADD(date, INTERVAL expr unit)
功能
在指定日期/时间上添加一个时间间隔
参数说明
date
:要处理的日期/时间值(可以是DATE, DATETIME或TIMESTAMP类型)expr
:要添加的间隔数值(可以是正数或负数)unit
:时间单位(见下方支持的单位)
支持的时间单位
MICROSECOND | SECOND | MINUTE | HOUR | DAY
| WEEK | MONTH | QUARTER | YEAR
| SECOND_MICROSECOND | MINUTE_MICROSECOND
| MINUTE_SECOND | HOUR_MICROSECOND
| HOUR_SECOND | HOUR_MINUTE
| DAY_MICROSECOND | DAY_SECOND
| DAY_MINUTE | DAY_HOUR
| YEAR_MONTH
使用示例
-- 加1天
SELECT DATE_ADD('2023-01-01', INTERVAL 1 DAY); -- 结果: 2023-01-02-- 加1个月
SELECT DATE_ADD('2023-01-31', INTERVAL 1 MONTH); -- 结果: 2023-02-28 (自动处理月末)-- 加1年
SELECT DATE_ADD('2020-02-29', INTERVAL 1 YEAR); -- 结果: 2021-02-28 (闰年自动调整)-- 加3小时30分钟
SELECT DATE_ADD('2023-01-01 12:00:00', INTERVAL '3:30' HOUR_MINUTE); -- 结果: 2023-01-01 15:30:00-- 使用负数表示减法
SELECT DATE_ADD('2023-01-01', INTERVAL -1 DAY); -- 结果: 2022-12-31
2. DATE_SUB 函数
基本语法
DATE_SUB(date, INTERVAL expr unit)
功能
与DATE_ADD相反,从指定日期/时间减去一个时间间隔
使用示例
-- 减1天
SELECT DATE_SUB('2023-01-01', INTERVAL 1 DAY); -- 结果: 2022-12-31-- 减1个月
SELECT DATE_SUB('2023-03-31', INTERVAL 1 MONTH); -- 结果: 2023-02-28-- 等同于DATE_ADD使用负数
SELECT DATE_SUB('2023-01-01', INTERVAL 1 DAY) = DATE_ADD('2023-01-01', INTERVAL -1 DAY); -- 结果: 1(TRUE)
3. 简写语法
MySQL还提供更简洁的日期加减写法:
-- 加1天
SELECT '2023-01-01' + INTERVAL 1 DAY;-- 减1个月
SELECT '2023-01-01' - INTERVAL 1 MONTH;
4. 实际应用场景
场景1:计算到期日
-- 贷款30天后到期
SELECT loan_date, DATE_ADD(loan_date, INTERVAL 30 DAY) AS due_date
FROM loans;
场景2:查找最近7天的记录
SELECT * FROM orders
WHERE order_date >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY);
场景3:处理订阅续期
-- 订阅续期1年
UPDATE subscriptions
SET end_date = DATE_ADD(end_date, INTERVAL 1 YEAR)
WHERE user_id = 1001;
5. 注意事项
-
自动调整无效日期:
SELECT DATE_ADD('2023-01-31', INTERVAL 1 MONTH); -- 返回2023-02-28
-
闰年处理:
SELECT DATE_ADD('2020-02-29', INTERVAL 1 YEAR); -- 返回2021-02-28
-
时间溢出处理:
SELECT DATE_ADD('2023-01-01 23:59:59', INTERVAL 1 SECOND); -- 返回2023-01-02 00:00:00
-
性能考虑:在WHERE条件中对列使用这些函数会导致索引失效
6. 与其他日期函数的对比
需求 | 推荐函数 | 示例 |
---|---|---|
计算未来/过去特定时间点 | DATE_ADD/DATE_SUB | DATE_ADD(now(), INTERVAL 1 HOUR) |
计算两个日期的差值 | DATEDIFF/TIMESTAMPDIFF | DATEDIFF(end_date, start_date) |
提取日期部分 | DATE_FORMAT/EXTRACT | EXTRACT(YEAR FROM date) |
获取当前日期/时间 | NOW/CURDATE | SELECT CURDATE(), NOW() |