Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql server:选择其总和与值匹配的行_Sql_Sql Server_Sql Server 2012_Subset Sum - Fatal编程技术网

sql server:选择其总和与值匹配的行

sql server:选择其总和与值匹配的行,sql,sql-server,sql-server-2012,subset-sum,Sql,Sql Server,Sql Server 2012,Subset Sum,以下是表T:- 下面是一个虚构的sql 预期结果是:- A B C 最好使用“A”型案例 我知道这个案子和组合有关 在现实世界中,客户从商店获得商品,由于他和商店之间的协议,他每周五付款。付款金额不是项目的确切总数 例如:他得到了5本50欧元=250欧元的书,周五他带来了150欧元,所以前3本书是完美匹配的-3*50=150。我需要找到那3本书的id 任何帮助都将不胜感激 要找到客户正在付款的图书的id,您需要与客户建立一张桌子,另一张桌子用来存储客户的订单以及他购买的产品。 否则就不可能知道付

以下是表T:-

下面是一个虚构的sql

预期结果是:-

A

B

C

最好使用“A”型案例

我知道这个案子和组合有关

在现实世界中,客户从商店获得商品,由于他和商店之间的协议,他每周五付款。付款金额不是项目的确切总数 例如:他得到了5本50欧元=250欧元的书,周五他带来了150欧元,所以前3本书是完美匹配的-3*50=150。我需要找到那3本书的id


任何帮助都将不胜感激

要找到客户正在付款的图书的id,您需要与客户建立一张桌子,另一张桌子用来存储客户的订单以及他购买的产品。
否则就不可能知道付款指的是什么产品。

要找到客户正在付款的图书的id,您需要与客户建立一个表,另一个表存储客户的订单以及他购买的产品。
否则,就不可能知道付款指的是什么产品。

如果您将问题限制为两个数字加起来等于一个值,解决方案如下:

SELECT t1.id, t1.num, t2.id,t2.num
FROM T t1 
INNER JOIN T t2
ON t1.id < t2.id
WHERE t1.num + t2.num  = 150

如果您还希望得到三个或更多数字的结果,可以通过使用上述查询作为递归SQL的基础来实现。不要忘记指定最大递归深度

如果将问题限制为两个数字加起来等于一个值,则解决方案如下:

SELECT t1.id, t1.num, t2.id,t2.num
FROM T t1 
INNER JOIN T t2
ON t1.id < t2.id
WHERE t1.num + t2.num  = 150

如果您还希望得到三个或更多数字的结果,可以通过使用上述查询作为递归SQL的基础来实现。不要忘记指定最大递归深度

您可以在MSSQL中使用递归查询来解决此问题


第一个递归查询构建一个累积和项的树,您可以在MSSQL中使用递归查询来解决这个问题


第一个递归查询构建一个项目树,其累积和为3,90;6,60或9,70;10,80,为什么第一个选项最受欢迎?我认为这个问题需要一种迭代方法,这不是SQL最适合的方法。@Lamak第一个选项最受欢迎,因为它的行数较少。但Lamak说,这是可选的:390和660、970和1080的组合也会产生2行,或者3,90;6,60或9,70;10,80,为什么第一个选项最受欢迎?我认为这个问题需要一种迭代方法,这不是SQL最适合的方法。@Lamak第一个选项最受欢迎,因为它的行数较少。但是optionalAs@Lamak说:390和660、970和1080的组合也会产生两行。当然有一个客户端id,我刚刚最小化了问题,所以表中只包含一个客户端的信息。当然有一个客户端id,我刚刚最小化了问题,所以这个表只包含一个客户端的信息,我对递归没有太多的了解。我会读更多关于递归的书来尝试你的方法。我对递归没有太多的知识。我将阅读更多关于递归的内容来尝试您的方法。太好了!第一行是预期结果!谢谢,太好了!第一行是预期结果!非常感谢。
id  num
-------
 1  50
 8  100
id  num
-------
 2  20
 7  30
 8  100
id  num
-------
 4  40
 5  10
 8  100
SELECT t1.id, t1.num, t2.id,t2.num
FROM T t1 
INNER JOIN T t2
ON t1.id < t2.id
WHERE t1.num + t2.num  = 150
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