Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

serwer sql :wybierz wiersze, których suma pasuje do wartości

Aby rozwiązać ten problem, możesz użyć zapytań rekurencyjnych w MSSQL.

Demo SQLFiddle

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak wykonać wyzwalacz tylko po zaktualizowaniu określonej kolumny (SQL Server)

  2. Konwertuj varchar na datetime w sql, który ma milisec

  3. Porównanie ciągów SQL uwzględniających wielkość liter

  4. Zaktualizuj tabelę o pola losowe

  5. SQL Server konwertuje kolumnę na kolumnę tożsamości