यह किसी भी चीज़ के रूप में व्यस्त है, लेकिन आपको वह चाहिए जो आपको चाहिए:
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
अंतरतम क्वेरी समूह आपके पीरियड्स को एक साथ ओवरलैपिंग समूहों में end_date तक फैलाते हैं जहां उपयुक्त हो। जैसा कि मैंने माना था कि end_date फ्लेक्स हो जाता है, पिछली बार पूरी तरह से संलग्न अवधि हो सकती है।
अगली रैपिंग क्वेरी प्रत्येक समूह से पूरी श्रृंखला निकालती है।
प्रत्येक समूह के लिए पूरे महीने की बाहरी क्वेरी अलग-अलग होती है। सभी समूह अंतरों को PERIOD_DIFF द्वारा निकटतम पूर्ण माह में पूर्णांकित किया जाता है।
दुर्भाग्य से मैं इसका परीक्षण नहीं कर सका क्योंकि SQLFiddle मुझ पर मर गया है।