Dit is allesbehalve hectisch, maar het zou je moeten geven wat je nodig hebt:
SELECT SUM(PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM a.end_date), EXTRACT(YEAR_MONTH FROM a.start_date))) months
FROM (
SELECT MIN(g.start_date) start_date, MAX(g.end_date) end_date
FROM (
SELECT @group_id := @group_id + (@end_date IS NULL OR o.start_date > @end_date) group_id,
start_date,
@end_date := DATE(CASE
WHEN (@end_date IS NULL OR o.start_date > @end_date) THEN o.end_date
ELSE GREATEST(o.end_date, @end_date)
END) end_date
FROM overlap o
JOIN (SELECT @group_id := 0, @end_date := NULL) init
ORDER BY o.start_date ASC
) g
GROUP BY g.group_id
) a
De binnenste zoekopdracht groepeert uw perioden in overlappende groepen, waarbij de einddatum waar nodig wordt uitgerekt. De einddatum buigt omdat ik aannam dat er perioden zouden kunnen zijn die volledig worden omsloten door de vorige.
De volgende terugloopquery haalt het volledige bereik uit elke groep.
De buitenste zoekopdracht somt de volledige maandverschillen op voor elke groep. Alle groepsverschillen worden per PERIOD_DIFF naar beneden afgerond op de dichtstbijzijnde volledige maand.
Helaas kon ik dit niet testen omdat SQLFiddle op mij is overleden.