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

sql server :sélectionnez les lignes dont la somme correspond à une valeur

Vous pouvez utiliser une requête récursive dans MSSQL pour résoudre ce problème.

Démo SQLFiddle

La première requête récursive construit un arbre d'éléments avec une somme cumulée <=150. La deuxième requête récursive prend des feuilles avec une somme cumulée =150 et génère tous ces chemins vers ses racines. Également dans les résultats finaux classés par ItemsCount vous obtiendrez donc les groupes préférés (avec un nombre minimal d'éléments) en premier.

WITH CTE as
( SELECT id,num,
         id as Grp,
         0 as parent,
         num as CSum,
         1 as cnt,
         CAST(id as Varchar(MAX)) as path
     from T where num<=150
  UNION all
  SELECT t.id,t.num,
         CTE.Grp as Grp, 
         CTE.id as parent,
         T.num+CTE.CSum as CSum,
         CTE.cnt+1 as cnt,
         CTE.path+','+CAST(t.id as Varchar(MAX)) as path
    from T 
  JOIN CTE on T.num+CTE.CSum<=150 
             and CTE.id<T.id 
),
BACK_CTE as
(select CTE.id,CTE.num,CTE.grp, 
         CTE.path ,CTE.cnt as cnt,
         CTE.parent,CSum 
    from CTE where CTE.CSum=150
  union all
  select CTE.id,CTE.num,CTE.grp,
         BACK_CTE.path,BACK_CTE.cnt, 
         CTE.parent,CTE.CSum 
   from CTE
   JOIN BACK_CTE on CTE.id=BACK_CTE.parent 
              and CTE.Grp=BACK_CTE.Grp
              and BACK_CTE.CSum-BACK_CTE.num=CTE.CSum
) 
select id,NUM,path, cnt as ItemsCount   from BACK_CTE order by cnt,path,Id