我有一张日期范围表:
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这样的单日。
答案 0 :(得分:5)
如果您的日期间隔不会嵌套或交叉,您可以使用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 | +------------+------------+
(fiddle就此而言)
要“完成”您的表格,您可以使用上面SELECT
查询的INSERT..SELECT
语法。