我只需要检索其大小字段的和值为< = 150的特定记录。 我有下面的表......
userid size
1 70
2 100
3 50
4 25
5 120
6 90
输出应该是......
userid size
1 70
3 50
4 25
例如,如果我们添加70,50,25,我们得到145,这是< = 150。
我如何编写查询来完成此任务?
答案 0 :(得分:5)
这是一个产生上述结果的查询:
SELECT * FROM `users` u
WHERE (select sum(size) from `users` where size <= u.size order by size) < 150
ORDER BY userid
但是,您描述的想要选择最接近给定大小的用户的问题是bin packing problem。这是NP-Hard问题,使用ANSI SQL无法轻松解决。但是,上面似乎返回了正确的结果,但实际上它只是从最小的项目开始,并继续添加项目,直到bin已满。
一般的,更有效的装箱算法是从最大的项目开始,并在适合时继续添加较小的装箱算法。该算法将选择用户5和4。
答案 1 :(得分:4)
你要找的是greedy algorithm.你不能用一个SQL语句真正做到这一点。
答案 2 :(得分:0)
它类似于subset sum problem。你肯定会进入指数时间......
有几种方法可以解决子集问题 N中的时间和指数最大 天真的算法就是循环 通过N个数字的所有子集, 对于他们每个人,检查是否 子集总和到正确的数字。该 运行时间为O(2 ^ N * N),因为 有2N子集,并检查 每个子集,我们需要总和N. 元件。
除非您可以将问题限制在较小的子集中。
答案 3 :(得分:0)
根据您的定义,您可以获得以下任何一个表格:
userid size userid size
1 70 2 100
userid size userid size
3 50 4 25
userid size userid size
5 120 6 90
userid size userid size
1 70 2 100
3 50 3 50
userid size userid size
1 70 2 100
4 25 4 25
userid size userid size
1 70 4 25
3 50 6 90
4 25
userid size userid size
4 25 3 50
5 120 6 90
SQL很难猜测。你的意思是说你想要总体规模在一定限度以下的大多数用户吗?您需要创建所有用户组合的临时表,然后选择总大小小于限制的临时表,然后选择具有最多用户的那个,可能还有最低用户ID等。无论哪种方式,由于第一步,它都不会很快。
答案 4 :(得分:0)
但是你想最大化结果数量还是最小化,或者你根本不关心?前两种情况是约束优化,应该有使用SQL的解决方案,后者(如上所述)需要贪婪策略。