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

faire des agrégations de sous-groupes dans sql en fonction d'une valeur de colonne

Vous pouvez attribuer un paramètre de regroupement en comptant le nombre de done enregistrements avant chaque enregistrement. Le reste n'est qu'une agrégation, bien que l'attribution d'une lettre à chaque groupe semble être une complication inutile :

select grp as record, min(Date) as DateBegin,
       max(case when Action = 'Done' then Date end) as DateEnd,
       count(*) as NumActions,
       sum(case when Action = 'Escalation' then 1 else 0 end) as NumEscalations
from (select e.*, coalesce(e2.grp, 0) as grp
      from example e outer apply
           (select count(*) as grp
            from example e2
            where e2.id < e.id and e2.Action = 'Done'
           ) e2
     ) e
group by grp;

Cette requête serait plus simple (et plus efficace) dans SQL Server 2012+, qui prend en charge les sommes cumulées.

MODIFIER :

Je remarque que j'utilise une sous-requête pour cela, mais ce n'est pas nécessaire. Cela peut être écrit comme :

      select coalesce(grp, 0) as record, min(Date) as DateBegin,
             max(case when Action = 'Done' then Date end) as DateEnd,
             count(*) as NumActions,
             sum(case when Action = 'Escalation' then 1 else 0 end) as NumEscalations
      from example e outer apply
           (select count(*) as grp
            from example e2
            where e2.id < e.id and e2.Action = 'Done'
           ) e2
      group by e2.grp