【实战总结】MySQL日期加减大全:日期计算、边界处理与性能优化详解

MySQL 日期加一天完全指南

一、基础日期加法

  1. 使用 DATE_ADD() 函数

    -- 当前日期加一天
    SELECT DATE_ADD(CURDATE(), INTERVAL 1 DAY);

    -- 指定日期加一天
    SELECT DATE_ADD('2024-01-15', INTERVAL 1 DAY);

    -- 日期时间加一天
    SELECT DATE_ADD('2024-01-15 14:30:00', INTERVAL 1 DAY);

  2. 使用 INTERVAL 简写

    -- 当前日期加一天
    SELECT CURDATE() + INTERVAL 1 DAY;

    -- 指定日期加一天
    SELECT '2024-01-15' + INTERVAL 1 DAY;

  3. 使用 ADDDATE() 函数

    -- ADDDATE 与 DATE_ADD 功能相同
    SELECT ADDDATE(CURDATE(), INTERVAL 1 DAY);
    SELECT ADDDATE('2024-01-15', 1); -- 第二个参数直接写数字

二、实战应用场景

场景1:查询明天的数据

复制代码
-- 查询明天到期的订单
SELECT * FROM orders 
WHERE expire_date = CURDATE() + INTERVAL 1 DAY;

-- 查询未来24小时内的活动
SELECT * FROM events 
WHERE start_time BETWEEN NOW() AND NOW() + INTERVAL 1 DAY;

场景2:数据统计和报表

复制代码
-- 统计最近7天每天的数据(包括明天)
SELECT 
    CURDATE() + INTERVAL (ones.n + 10*tens.n) DAY as stat_date,
    COUNT(orders.id) as order_count
FROM 
    (SELECT 0 n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 
     UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) ones
CROSS JOIN 
    (SELECT 0 n UNION SELECT 1) tens
LEFT JOIN orders ON DATE(orders.created_at) = CURDATE() + INTERVAL (ones.n + 10*tens.n) DAY
WHERE (ones.n + 10*tens.n) BETWEEN 0 AND 6
GROUP BY stat_date;

场景3:自动设置默认日期

复制代码
-- 创建表时设置默认过期时间为明天
CREATE TABLE temporary_data (
    id INT PRIMARY KEY AUTO_INCREMENT,
    data_content TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    expire_date DATE DEFAULT (CURDATE() + INTERVAL 1 DAY)
);

-- 插入数据,自动设置明天过期
INSERT INTO temporary_data (data_content) VALUES ('临时数据');

三、时间单位大全

MySQL 支持的各种时间间隔单位:

| 单位 | 说明 | 示例 | |||| | ​​MICROSECOND​​ | 微秒 | ​​INTERVAL 1000 MICROSECOND​​ | | ​​SECOND​​ | 秒 | ​​INTERVAL 30 SECOND​​ | | ​​MINUTE​​ | 分钟 | ​​INTERVAL 15 MINUTE​​ | | ​​HOUR​​ | 小时 | ​​INTERVAL 2 HOUR​​ | | ​​DAY​​ | 天 | ​​INTERVAL 1 DAY​​ | | ​​WEEK​​ | 周 | ​​INTERVAL 1 WEEK​​ | | ​​MONTH​​ | 月 | ​​INTERVAL 1 MONTH​​ | | ​​QUARTER​​ | 季度 | ​​INTERVAL 1 QUARTER​​ | | ​​YEAR​​ | 年 | ​​INTERVAL 1 YEAR​​ |

复杂时间计算示例

复制代码
-- 加1天2小时30分钟
SELECT NOW() + INTERVAL '1 2:30' DAY_MINUTE;

-- 加1年6个月
SELECT CURDATE() + INTERVAL '1-6' YEAR_MONTH;

-- 精确时间计算
SELECT '2024-01-15 14:30:00' + INTERVAL '1 02:30:45' DAY_SECOND;

四、日期减法

使用 DATE_SUB() 函数

复制代码
-- 当前日期减一天
SELECT DATE_SUB(CURDATE(), INTERVAL 1 DAY);

-- 指定日期减一天
SELECT DATE_SUB('2024-01-15', INTERVAL 1 DAY);

使用 INTERVAL 负数

复制代码
-- 日期减一天(推荐)
SELECT CURDATE() + INTERVAL -1 DAY;

-- 等同于
SELECT CURDATE() - INTERVAL 1 DAY;

五、处理边界情况

  1. 月末日期处理

    -- 自动处理月末(2024-01-31 加一天 → 2024-02-01)
    SELECT DATE_ADD('2024-01-31', INTERVAL 1 DAY);

    -- 闰年处理(2024-02-28 加一天 → 2024-02-29)
    SELECT DATE_ADD('2024-02-28', INTERVAL 1 DAY);

  2. 时间戳处理

    -- 时间戳加一天
    SELECT FROM_UNIXTIME(UNIX_TIMESTAMP() + (24 * 60 * 60));

    -- 指定时间戳加一天
    SELECT FROM_UNIXTIME(1705303845 + (24 * 60 * 60));

  3. 时区处理

    -- 考虑时区的日期计算
    SELECT
    CONVERT_TZ(NOW(), '+00:00', '+08:00') as beijing_time,
    CONVERT_TZ(NOW(), '+00:00', '+08:00') + INTERVAL 1 DAY as beijing_tomorrow;

六、性能优化技巧

  1. 避免在 WHERE 条件中使用函数

    -- ❌ 不推荐:无法使用索引
    SELECT * FROM orders
    WHERE DATE_ADD(created_date, INTERVAL 1 DAY) = '2024-01-16';

    -- ✅ 推荐:可以使用索引
    SELECT * FROM orders
    WHERE created_date = '2024-01-15';

  2. 使用预计算的值

    -- 在应用层计算好日期
    SET @tomorrow = CURDATE() + INTERVAL 1 DAY;

    SELECT * FROM schedule
    WHERE schedule_date = @tomorrow;

  3. 创建函数索引(MySQL 8.0+)

    -- 创建虚拟列并建立索引
    ALTER TABLE orders
    ADD COLUMN expire_date_virtual DATE
    GENERATED ALWAYS AS (created_date + INTERVAL 30 DAY) VIRTUAL;

    CREATE INDEX idx_expire_date ON orders(expire_date_virtual);

七、实际业务案例

案例1:会员到期提醒

复制代码
-- 查询明天到期的会员
SELECT 
    user_id,
    username,
    expire_date,
    expire_date + INTERVAL 1 DAY as grace_period_end
FROM members 
WHERE expire_date = CURDATE() + INTERVAL 1 DAY;

-- 批量续费一个月
UPDATE members 
SET expire_date = expire_date + INTERVAL 1 MONTH 
WHERE expire_date < CURDATE();

案例2:活动日程管理

复制代码
-- 生成未来7天的活动日历
SELECT 
    CURDATE() + INTERVAL n DAY as activity_date,
    CASE DAYOFWEEK(CURDATE() + INTERVAL n DAY)
        WHEN 1 THEN '周日'
        WHEN 7 THEN '周六'
        ELSE '工作日'
    END as day_type
FROM (
    SELECT 0 n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 
    UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
) days;

案例3:数据保留策略

复制代码
-- 删除30天前的数据
DELETE FROM user_logs 
WHERE created_at < CURDATE() - INTERVAL 30 DAY;

-- 归档明天之前的数据
INSERT INTO logs_archive 
SELECT * FROM user_logs 
WHERE created_at < CURDATE() + INTERVAL 1 DAY;

八、日期格式化输出

格式化日期结果

复制代码
-- 基础格式化
SELECT DATE_FORMAT(CURDATE() + INTERVAL 1 DAY, '%Y-%m-%d') as tomorrow;

-- 中文格式
SELECT DATE_FORMAT(CURDATE() + INTERVAL 1 DAY, '%Y年%m月%d日') as chinese_tomorrow;

-- 完整日期时间格式
SELECT DATE_FORMAT(NOW() + INTERVAL 1 DAY, '%Y-%m-%d %H:%i:%s') as tomorrow_datetime;

业务场景格式化

复制代码
-- 邮件模板中的日期
SELECT 
    CONCAT(
        '您的试用期将于 ',
        DATE_FORMAT(CURDATE() + INTERVAL 1 DAY, '%M %D, %Y'),
        ' 到期'
    ) as reminder_message;

-- 报表中的日期显示
SELECT 
    DATE_FORMAT(event_date, '%W, %b %d') as display_date,
    event_name
FROM events 
WHERE event_date BETWEEN CURDATE() AND CURDATE() + INTERVAL 7 DAY;

九、错误处理与验证

  1. 无效日期处理

    -- 安全日期计算(避免无效日期)
    SELECT
    DATE_ADD('2024-01-32', INTERVAL 1 DAY) as invalid_result, -- 返回 NULL
    COALESCE(DATE_ADD('2024-01-32', INTERVAL 1 DAY), CURDATE()) as safe_result;

  2. 日期验证函数

    -- 验证日期是否有效
    SELECT
    '2024-02-30' as test_date,
    CASE
    WHEN DATE('2024-02-30') IS NULL THEN '无效日期'
    ELSE '有效日期'
    END as validation_result;

  3. 边界测试

    -- 测试各种边界情况
    SELECT
    DATE_ADD('9999-12-31', INTERVAL 1 DAY) as max_date,
    DATE_ADD('1000-01-01', INTERVAL -1 DAY) as min_date,
    DATE_ADD('2024-12-31', INTERVAL 1 DAY) as year_end,
    DATE_ADD('2024-02-28', INTERVAL 1 DAY) as leap_year;

十、实用函数速查

| 需求 | 推荐写法 | 说明 | ||-|| | 当前日期加一天 | ​​CURDATE() + INTERVAL 1 DAY​​ | 最简洁 | | 指定日期加一天 | ​​DATE_ADD('2024-01-15', INTERVAL 1 DAY)​​ | 最清晰 | | 日期时间加一天 | ​​NOW() + INTERVAL 1 DAY​​ | 包含时间 | | 批量更新日期 | ​​UPDATE table SET date_col = date_col + INTERVAL 1 DAY​​ | 批量操作 | | 条件日期计算 | ​​CASE WHEN condition THEN date_col + INTERVAL 1 DAY ELSE date_col END​​ | 条件计算 |

总结

核心要点:

  1. 推荐写法​CURDATE() + INTERVAL 1 DAY​(最简洁直观)
  2. 函数选择​DATE_ADD()​​+ INTERVAL​ 功能相同,后者更简洁
  3. 边界处理:MySQL自动处理月末、闰年等特殊情况
  4. 性能注意:避免在WHERE条件中对字段使用日期函数

记住这个万能公式:

复制代码
日期/时间 + INTERVAL 数字 时间单位

通过掌握这些日期计算方法,你可以轻松处理各种业务场景中的日期逻辑!另外搭配便捷的80kmMYSQL备份工具,可定时备份、异地备份,MYSQL导出导入。可本地连接LINUX里的MYSQL,简单便捷。可以大大地提高工作效率喔。

相关推荐
v***913014 分钟前
Spring+Quartz实现定时任务的配置方法
android·前端·后端
wilsend28 分钟前
Android Studio 2024版新建java项目和配置环境下载加速
android
兰琛1 小时前
Android Compose展示PDF文件
android·pdf
走在路上的菜鸟2 小时前
Android学Dart学习笔记第四节 基本类型
android·笔记·学习
百锦再2 小时前
第21章 构建命令行工具
android·java·图像处理·python·计算机视觉·rust·django
skyhh4 小时前
Android Studio 最新版汉化
android·ide·android studio
路人甲ing..4 小时前
Android Studio 快速的制作一个可以在 手机上跑的app
android·java·linux·智能手机·android studio
携欢7 小时前
PortSwigger靶场之Web shell upload via path traversal靶场通关秘籍
android
消失的旧时光-194314 小时前
Android ADB指令大全详解
android·adb
ashcn200117 小时前
opengl 播放视频的android c++ 方案
android·c++ opengl es