MYSQL查询两个时间之间的日期列表

本文介绍四种不同的方法来查询MySQL中两个特定日期之间的所有日期。这些方法包括使用临时表、动态SQL、存储过程及多表联合生成日期序列。

时间:2016-11-21 13:04:11

这个一般用于统计,今天在开发一个拆线时用到了。需要把日期来显示在X轴上,直接百度了下,方法有好多,

找了一个最实用的(需要建一张临时表)

CREATE TABLE num (i INT);
 
INSERT INTO num (i)
VALUES
    (0),
    (1),
    (2),
    (3),
    (4),
    (5),
    (6),
    (7),
    (8),
    (9);
 
SELECT
    adddate('2012-09-01', numlist.id) AS 'date'
FROM
    (
        SELECT
            n1.i + n10.i * 10 + n100.i * 100 AS id
        FROM
            num n1
        CROSS JOIN num AS n10
        CROSS JOIN num AS n100
    ) AS numlist
WHERE
    adddate('2012-09-01', numlist.id) <= '2012-09-10';

QQ截图20161121125816.jpg

方法2:

-- 定义自增变量
set @i = -1;
-- 创建指定日期间记录数天数需要 加 1
set @sql = repeat(" select 1 union all",-datediff('2012-09-01','2012-09-10')+1);
-- 将最后一个union all 去掉,这里前边加1个空格,就不用在减1了
set @sql = left(@sql,length(@sql)-length(" union all"));
-- 拼接sql
set @sql = concat("select date_add('2012-09-01',interval @i:=@i+1 day) as date from (",@sql,") as tmp");
 
prepare stmt from @sql;
execute stmt;

201209210113169090.jpg

方法三存储过程(没测试):

DELIMITER $$
 
DROP PROCEDURE IF EXISTS DayRangeProc$$
 
CREATE PROCEDURE DayRangeProc(IN start_date datetime , IN end_date datetime )
      BEGIN
              DECLARE temp  INT;
              DECLARE range_day  INT;
 
              SET temp = 0;
              SET range_day = (SELECT DATEDIFF(end_date,start_date));
 
              WHILE temp  <= range_day DO
                    select ADDDATE(start_date, temp);
                    SET temp = temp + 1;
              END WHILE;
      END$$
 
  DELIMITER ;
 
Call DayRangeProc('2010-9-1','2010-9-10');

方法4:

SELECT date_series.date AS date
    FROM (
        SELECT ADDDATE('2012-09-01', INTERVAL t4.i*1000 + t3.i*100 + t2.i*10 + t1.i DAY) AS date
        FROM (SELECT 0 i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t1
        CROSS JOIN (SELECT 0 i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2
        CROSS JOIN (SELECT 0 i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t3
        CROSS JOIN (SELECT 0 i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t4
    ) date_series

    WHERE date_series.date BETWEEN '2012-09-01' AND '2012-09-10'
    GROUP BY date_series.date
    ORDER BY date_series.date

MySQL查询两个日期范围内的数据,可以通过 `SELECT` 语句结合 `WHERE` 子句实现。假设你的表中有一个日期时间列(例如 `created_at`),并且你想筛选出在这个列的某个日期区间内的记录,可以使用以下语法: ```sql SELECT * FROM your_table_name WHERE created_at BETWEEN 'start_date' AND 'end_date'; ``` 这里需要注意几点: - `'start_date'` 和 `'end_date'` 应该是符合 MySQL 日期格式的字符串(如 `YYYY-MM-DD HH:MM:SS`)[^2]。 - 如果日期存储的是 `DATE` 类型而不是 `DATETIME`,则不需要提供具体的时间部分。 ### 示例 假设你有一个名为 `orders` 的表,其中包含一个 `order_date` 列,你想查找 `order_date` 在 `2023-10-01` 到 `2023-10-31` 之间的订单记录: ```sql SELECT * FROM orders WHERE order_date BETWEEN '2023-10-01' AND '2023-10-31'; ``` 如果 `order_date` 是 `DATETIME` 类型,并且你想指定精确的时间点,比如从 `2023-10-01 08:00:00` 到 `2023-10-31 17:00:00`,你可以这样写: ```sql SELECT * FROM orders WHERE order_date BETWEEN '2023-10-01 08:00:00' AND '2023-10-31 17:00:00'; ``` 此外,如果你需要动态地获取最近一天的数据,可以使用 `NOW()` 函数与 `DATE_SUB()` 函数来构造查询条件,例如获取过去24小时内的数据: ```sql SELECT * FROM stats WHERE STR_TO_DATE(timespan, "%W, %b %d %Y, %h:%i:%s %p") >= DATE_SUB(NOW(), INTERVAL 1 DAY); ``` 这段 SQL 使用了 `STR_TO_DATE()` 函数将非标准格式的时间字符串转换为 MySQL 可识别的日期格式,然后与当前时间减去一天进行比较[^3]。 ### 注意事项 - 确保字段类型与查询中的日期格式一致。如果字段是 `DATE` 类型,则不应包含时间部分。 - 如果启用了 `NO_ZERO_DATE` 模式或严格模式,应确保插入或查询时不会使用非法日期值,如 `'0000-00-00'`[^5]。 - 对于频繁更新的记录,考虑使用 `LOW_PRIORITY` 或 `DELAYED` 插入策略以避免阻塞读取操作[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值