[英]Mysql Find missing date ranges
I have a table with date ranges: 我有一个日期范围的表:
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');
I want to complete this table with missing date ranges in 2014. In this case that would be: 我想在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
Any mysql query suggestions? 任何MySQL查询建议?
Edit 编辑
Better use these values: 更好地使用这些值:
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');
Edit 2 编辑2
I am almost there with this: 我几乎在那里:
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;
However, this query returns wrong results for the following intervals set: 但是,对于以下时间间隔集,此查询返回错误的结果:
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');
It seems it cannot handle single days like 2014-07-31 - 2014-07-31. 似乎无法处理像2014-07-31-2014-07-31这样的单日。
In case if your date intervals will not be nested or intersecting, you can use trick with JOIN
to produce result set. 如果您的日期间隔不会被嵌套或相交,可以在
JOIN
使用把戏来生成结果集。 So, to select desired record set, you'll need: 因此,要选择所需的记录集,您需要:
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;
that will result in 这将导致
+------------+------------+ | 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 | +------------+------------+
( fiddle for this is here) (为此提琴 )
To "complete" your table you may use INSERT..SELECT
syntax with SELECT
query above. 要“完成”表,您可以对上面的
SELECT
查询使用INSERT..SELECT
语法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.