Esto es agitado como cualquier cosa, pero debería darte lo que necesitas:
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
La consulta más interna agrupa sus períodos en grupos superpuestos que amplían la fecha_finalización cuando corresponde. El end_date se flexiona ya que asumí que podría haber períodos completamente encerrados por el anterior.
La siguiente consulta de ajuste extrae el rango completo de cada grupo.
La consulta externa resume las diferencias de mes completo para cada grupo. Todas las diferencias de grupo se redondean hacia abajo al mes completo más cercano por PERIOD_DIFF.
Desafortunadamente, no pude probar esto porque SQLFiddle murió en mí.