Quantcast
Viewing all articles
Browse latest Browse all 2

如何生成指定日期之间的日期列表?

实际应用中,我们期望有这样一个时间表,包含两个指定日期之间的所有日期,便于我们在统计等情况下用到。例如,我们给出2013-01-01和2013-01-13,就可以得到一张表内保存了如下数据:

  • 2013-01-01
  • 2013-01-02
  • 2013-01-03
  • 2013-01-04
  • 2013-01-05
  • 2013-01-06
  • 2013-01-07
  • 2013-01-08
  • 2013-01-09
  • 2013-01-10
  • 2013-01-11
  • 2013-01-12
  • 2013-01-13

如何在不依赖于其他表的情况下使用SQL完成该需求呢?

本题来源stackoverflow

首先想到的,肯定是循环,指定了开始日期和结束日期,循环插入到一张表中即可。
MySQL可以在存储过程中实现,其他系统都可以类似实现,具体如下:
create table date_intervals
(
	d date not null primary key
);

CREATE PROCEDURE make_intervals
(
	in startdate date,
	in enddate date,
	out o_rtcd  integer,
    out o_msg varchar(300)
)
BEGIN
/*
description:make days list between startdate and enddate
example: call make_intervals('2013-1-1','2013-1-13',@rtcd, @msg);
         select @rtcd,@msg;
author:  Carl
create date:  2013-05-30
*/
	/*----------- local variables ---------------*/
	declare thisDate date;

	/*----------- main begin---------------*/
	set o_rtcd = 0;
        set o_msg = 'ok';

	set thisDate=startdate;

	repeat
		insert into date_intervals values(thisDate);
		set thisDate=thisDate + interval 1 day;
	UNTIL thisDate > enddate
	end repeat;

	/*----------- main end ---------------*/
END

运行如下:

mysql> call make_intervals('2013-1-1','2013-1-13',@rtcd, @msg);
Query OK, 1 row affected (0.02 sec)

mysql> select @rtcd,@msg;
+-------+------+
| @rtcd | @msg |
+-------+------+
|     0 | ok   |
+-------+------+
1 row in set (0.00 sec)

mysql> select * from date_intervals;
+------------+
| d          |
+------------+
| 2013-01-01 |
| 2013-01-02 |
| 2013-01-03 |
| 2013-01-04 |
| 2013-01-05 |
| 2013-01-06 |
| 2013-01-07 |
| 2013-01-08 |
| 2013-01-09 |
| 2013-01-10 |
| 2013-01-11 |
| 2013-01-12 |
| 2013-01-13 |
+------------+
13 rows in set (0.00 sec)

在Oracle/SqlServer/DB2中,支持with来实现递归,如下展示了SqlServer的一个实现,其他系统类似:

BEGIN
    DECLARE @startDate DATETIME;
    DECLARE @endDate DATETIME;

    SET @startDate = '2013-01-01';
    SET @endDate = '2013-01-31';

    WITH dates(d) AS
    (
        SELECT @startdate as d
        UNION ALL
        SELECT DATEADD(day,1,d)
        FROM dates
        WHERE d < @enddate
    )
    SELECT d
    FROM dates
END

The post 如何生成指定日期之间的日期列表? appeared first on SQLParty.


Viewing all articles
Browse latest Browse all 2

Trending Articles