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