PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Trouvez des lignes avec des plages de dates d'ajournement et accumulez leurs durées

Il s'agit d'un problème de lacunes et d'îlots. Dans ce cas, vous pouvez utiliser lag() pour voir où commence une île, puis une somme cumulée.

L'opération finale est une agrégation (à l'aide des fonctions de fenêtre) :

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;