यह एक अंतराल और द्वीपों की समस्या है। इस मामले में आप lag()
. का उपयोग कर सकते हैं यह देखने के लिए कि एक द्वीप कहाँ से शुरू होता है और फिर एक संचयी योग।
अंतिम ऑपरेशन कुछ एकत्रीकरण है (विंडो फ़ंक्शंस का उपयोग करके):
SELECT p.*,
(Max(ends_on) OVER (PARTITION BY location_id, grp) - Min(starts_on) OVER (PARTITION BY location_id, grp) ) + 1 AS duration,
Array_agg(p.id) OVER (PARTITION BY location_id)
FROM (SELECT p.*,
Count(*) FILTER (WHERE prev_eo < starts_on - INTERVAL '1 day') OVER (PARTITION BY location_id ORDER BY starts_on) AS grp
FROM (SELECT id, starts_on, ends_on, location_id, holiday_or_vacation_type_id,
lag(ends_on) OVER (PARTITION BY location_id ORDER BY (starts_on)) AS prev_eo
FROM periods
) p
) p;