Dies ist ein hartes Problem, das schwieriger gemacht wird, weil Sie MySQL verwenden. Hier ist eine Idee. Finden Sie das Anfangsdatum aller Feiertage in jeder Gruppe. Dann behandelt eine kumulative Summe des Flags für den "Anfang" die Gruppen. Der Rest ist nur Aggregation.
Folgendes sollte das tun, was Sie wollen, vorausgesetzt, Sie sind keine doppelten Datensätze:
select min(holiday_begin) as holiday_begin, max(holiday_end) as holiday_end
from (select lh.*, (@grp := @grp + group_flag) as grp
from (select lh.*,
(case when not exists (select 1
from lessons_holidays lh2
where lh2.holiday_begin <= lh.holiday_end and
lh2.holiday_end > lh.holiday_begin and
(lh2.holiday_begin <> lh.holiday_begin or
lh2.holiday_end < lh.holiday_end)
)
then 1 else 0
end) as group_flag
from lessons_holidays lh
) lh cross join
(select @grp := 0) params
order by holiday_begin, holiday_end
) lh
group by grp;
Wenn Sie Duplikate haben, verwenden Sie nur select distinct
auf den innersten Verweise auf den Tisch.
Here ist eine SQL Fiddle.
EDIT:
Diese Version erscheint, besser zu arbeiten:
select min(holiday_begin) as holiday_begin, max(holiday_end) as holiday_end
from (select lh.*, (@grp := @grp + group_flag) as grp
from (select lh.*,
(case when not exists (select 1
from lessons_holidays lh2
where lh2.holiday_begin <= lh.holiday_begin and
lh2.holiday_end > lh.holiday_begin and
lh2.holiday_begin <> lh.holiday_begin and
lh2.holiday_end <> lh.holiday_end
)
then 1 else 0
end) as group_flag
from lessons_holidays lh
) lh cross join
(select @grp := 0) params
order by holiday_begin, holiday_end
) lh
group by grp;
Wie here dargestellt.
Dies ist ziemlich schwierig in MySQL zu tun. Haben Sie andere Datenbanken, die Sie verwenden können? –