Nel caso in cui i tuoi intervalli di date non siano nidificati o intersecanti, puoi usare il trucco con JOIN
per produrre un set di risultati. Quindi, per selezionare il set di record desiderato, avrai bisogno di:
SELECT
*
FROM
(SELECT
ends.point AS date_start,
starts.point AS date_end
FROM
(SELECT
d.date_end+INTERVAL 1 DAY AS point,
@n:[email protected]+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:[email protected]+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;
che risulterà 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 | +------------+------------+
(violino per questo è qui)
Per "completare" la tua tabella puoi utilizzare INSERT..SELECT
sintassi con SELECT
query sopra.