Во-первых, даты нужно как-то связать в цепочки.
Я это сделал с помощью LEFT JOIN таблицы с самой собой. В секции ON указал "T2.d = T1.d + 1". (Переход цепочки через месяц я не учитывал, но думаю, что достаточно в эту секцию добавить MONTH(T1.d) = MONTH(t2.d).)
При таком объединении таблиц вторая дата будет NULL, когда первая дата будет являться концом цепочки.
При RIGHT JOIN всё наоборот: первая дата NULL, когда вторая дата - начало цепочки.
Во-вторых, нужно выбрать начальные и конечные даты диапазонов.
Здесь всё просто: есть пара дат, и один из элементов пары NULL. Отображаем это в секции WHERE.
В-третьих, нужно оставшиеся даты упорядочить.
В MySQL с этим проблема, как в остальных местах - не знаю. Суть проблемы в том, что ORDER BY работает только на конечных запросах, а не в подзапросах. Пришлось изгалаться с помощью GROUP BY, с которым я не работал, поэтому не могу гарантировать, что запрос действительно правильный. Но если бы ORDER BY работал, то в результате получились бы две таблички с одинаковым количеством упорядоченных дат. В одной табличке - начала, а в другой - конец.
В четвёртых, объединим начальные и конечные даты.
Вот, что у меня получилось.
SELECT b, min(e) FROM
(SELECT T2.d AS b FROM dates_ilovb AS T1 RIGHT JOIN dates_ilovb AS T2 ON T2.d = T1.d + 1 WHERE T1.d IS NULL) AS TB
LEFT JOIN
(SELECT T1.d AS e FROM dates_ilovb AS T1 LEFT JOIN dates_ilovb AS T2 ON T2.d = T1.d + 1 WHERE T2.d IS NULL) AS TE
ON TB.b <= TE.e
GROUP BY b
ORDER BY b;