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

Somme de la plage de dates sans compter les chevauchements dans mysql

C'est mouvementé comme tout, mais cela devrait vous apporter ce dont vous avez besoin :

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 requête la plus interne regroupe vos périodes dans des groupes qui se chevauchent, étirant la date de fin, le cas échéant. Le end_date fléchit car j'ai supposé qu'il pourrait y avoir des périodes complètement entourées par le précédent.

La requête d'encapsulation suivante extrait la plage complète de chaque groupe.

La requête externe résume les différences mensuelles complètes pour chaque groupe. Tous les diffs de groupe sont arrondis au mois complet le plus proche par PERIOD_DIFF.

Malheureusement, je n'ai pas pu tester cela car SQLFiddle est mort sur moi.