我有一个日期范围的表:
create table d ( date_start date, date_end date ); insert into d values('2014-03-05', '2014-04-10'); insert into d values('2014-05-01', '2014-06-05'); insert into d values('2014-07-10', '2014-08-15');
我想在2014年填写缺少日期范围的表格。在这种情况下,该表格应为:
2014-01-01 - 2014-03-04 2014-04-11 - 2014-04-30 2014-06-06 - 2014-07-09 2014-08-16 - 2014-12-31
任何MySQL查询建议?
编辑
更好地使用这些值:
create table d ( date_start date, date_end date ); insert into d values('2014-06-01', '2014-06-30'); insert into d values('2014-07-01', '2014-08-03'); insert into d values('2014-09-01', '2014-09-30');
编辑2
我几乎可以做到这一点:
SELECT date_start, date_end FROM (SELECT ends.point AS date_start, starts.point AS date_end FROM (SELECT d.date_end+INTERVAL 1 DAY AS point, @n:=@n+1 AS num FROM d CROSS JOIN (SELECT @n:=1) AS init0 ORDER BY date_start ) AS ends INNER JOIN (SELECT d.date_start-INTERVAL 1 DAY AS point, @m:=@m+1 AS num FROM d CROSS JOIN (SELECT @m:=0) AS init1 ORDER BY date_start ) AS starts ON ends.num=starts.num UNION ALL SELECT '2014-01-01', MIN(date_start) - INTERVAL 1 DAY FROM d WHERE date_start>='2014-01-01' UNION ALL SELECT MAX(date_end)+INTERVAL 1 DAY, '2014-12-31' FROM d WHERE date_end <= '2014-12-31' ) as dates WHERE date_start < date_end ORDER BY date_start;
但是,对于以下时间间隔集,此查询返回错误的结果:
create table d (date_start date, date_end date); insert into d values('2014-01-01', '2014-01-09'); insert into d values('2014-01-10', '2014-03-15'); insert into d values('2014-03-16', '2014-04-20'); insert into d values('2014-05-01', '2014-07-30'); insert into d values('2014-08-01', '2014-09-30'); insert into d values('2014-12-25', '2014-12-31');
似乎无法处理像2014-07-31-2014-07-31这样的单日。
如果您的日期间隔不会被嵌套或相交,则可以使用把戏与JOIN产生结果集。因此,要选择所需的记录集,您需要:
JOIN
SELECT * FROM (SELECT ends.point AS date_start, starts.point AS date_end FROM (SELECT d.date_end+INTERVAL 1 DAY AS point, @n:=@n+1 AS num FROM d CROSS JOIN (SELECT @n:=1) AS init0 ) AS ends INNER JOIN (SELECT d.date_start-INTERVAL 1 DAY AS point, @m:=@m+1 AS num FROM d CROSS JOIN (SELECT @m:=0) AS init1 ) AS starts ON ends.num=starts.num UNION ALL SELECT '2014-01-01', MIN(date_start) - INTERVAL 1 DAY AS date_end FROM d HAVING date_end>'2014-01-01' UNION ALL SELECT MAX(date_end)+INTERVAL 1 DAY AS date_start, '2014-12-31' FROM d HAVING date_start<'2014-12-31' ) as dates WHERE date_start<=date_end ORDER BY date_start;
这将导致
+ ------------ + ------------ + | date_start | date_end | + ------------ + ------------ + | 2014-01-01 | 2014-03-04 | | 2014-04-11 | 2014-04-30 | | 2014-06-06 | 2014-07-09 | | 2014-08-16 | 2014-12-31 | + ------------ + ------------ +
(这是小提琴在这里)
要“完成”表,您可以INSERT..SELECT在SELECT上面的查询中使用语法。
INSERT..SELECT
SELECT