Aby rozwiązać ten problem, możesz użyć zapytań rekurencyjnych w MSSQL.
Pierwsze zapytanie rekurencyjne buduje drzewo elementów o skumulowanej sumie <=150. Drugie rekurencyjne zapytanie pobiera liście o skumulowanej sumie =150 i wyprowadza wszystkie takie ścieżki do swoich korzeni. Również w ostatecznych wynikach uporządkowanych według ItemsCount
więc najpierw otrzymasz preferowane grupy (z minimalną liczbą elementów).
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