MySQL 查找小计
Posted
技术标签:
【中文标题】MySQL 查找小计【英文标题】:MySQL finding subtotals 【发布时间】:2010-09-28 16:24:26 【问题描述】:编辑:
有人告诉我,让你们阅读意味着我得到的关注更少。我很抱歉。这是一个更简单的版本:
比尔从一家商店买了价值 100 美元的商品。
他想退回足够多的物品,以准确地拿回 30 美元。
商店有一个退货系统,可以帮助他做到这一点。
这是他扫描物品后的数据:
item ¦ price ¦
socks 4.00
cheap tv 22.00
book on tape 9.00
book on paper 7.00
party hats 3.00
picture frame 10.00
hammer 5.00
juicer 16.00
mysql guide 24.00
total items ¦ total price ¦
9 100.00
Option 1
===============
item ¦ price ¦
cheap tv 22.00
party hats 3.00
hammer 5.00
===============
Option 2
===============
item ¦ price ¦
socks 4.00
picture frame 10.00
juicer 16.00
===============
Option 3
===============
item ¦ price ¦
book on tape 9.00
hammer 5.00
juicer 16.00
我可能错过了一些选项,因为这一切都是我编造的。
所以,最大的问题是:
有没有办法(可能使用 GROUP BY)让一个查询返回任何可能的项目组合?
谢谢!
一个
【问题讨论】:
你应该努力缩短你的问题的长度——我怀疑它对于大多数人来说太长了。浏览问题文本后,似乎这确实很简单,但您应该让我们更容易回答。 另外,问题文本听起来很像家庭作业。 :) 如果你指的是风格,那是故意的。想给它那种“单词问题”的感觉。如果你的意思是这听起来像是我想让你们做我的功课,我恳求无辜。我正在设计它的工作时间表系统,以使经理和工人的生活更轻松。 :p 好吧,你听起来很有说服力 :-) 只是我的两分钱...... 【参考方案1】:您要求的所有子集的总和正好为 30 美元。
这听起来很像subset sum problem 和knapsack problem,所以我强烈怀疑你可以通过简单的查询来做到这一点。您可能不得不求助于 T-SQL,但即便如此也可能看起来很难看。
我认为编程是这里的路。
【讨论】:
SQL 通过连接枚举组合。您需要无限数量的连接来计算所有项目的所有组合。这明确不能在 SQL 中完成。 但是 T-SQL 是图灵完备的...... :) 但它可能看起来很难看。 我期待看到在 MySQL 中运行的 T-SQL 解决方案...(gd&r)【参考方案2】:如果项目数量足够少,您可以使用 SQL 强制执行此操作。这可能是一个快速编写的解决方案,但您可能想做一些更聪明的事情。听起来像是 NP 完整的“knapsack problem”。
如果项目的数量很大,您将需要深入研究动态规划算法。您必须问问自己这对您的应用程序有多重要。
如果项目的数量相对较少,您可以强制执行此操作。查找 1,2 或 3 个匹配项的组合的蛮力 SQL 语句(这是您所要求的)如下。如果这不令人满意,那么 SQL 可能不是这项工作的正确工具。
SELECT
i1.id AS id1,
NULL AS id2,
NULL AS id3,
i1.amount
FROM
items i1
UNION ALL
SELECT
i1.id AS id1,
i2.id AS id2,
i3.id AS id3,
i1.amount + i2.amount AS total
FROM
items i1,
items i2
WHERE
i1.amount + i2.amount = 30 AND
i1.id <> i2.id AND
i1.id <> i3.id
UNION ALL
SELECT
i1.id AS id1,
i2.id AS id2,
i3.id AS id3,
i1.amount + i2.amount + i3.amount AS total
FROM
items i1,
items i2,
items i3
WHERE
i1.amount + i2.amount + i3.amount = 30 AND
i1.id <> i2.id AND
i1.id <> i3.id AND
i2.id <> i3.id
在 Oracle 中,您将使用 CUBE 函数将其转换为通用版本,不确定是否与 MySQL 等效。
【讨论】:
大道具为我指出了这种情况的名称。我花了几天时间研究三角数,看看情况是否可以简化。我认为毕竟提供此功能实际上并不是一个好主意。【参考方案3】:我认为 group by 做不到。
我想不出比使用您选择的编程语言或使用存储过程查找/尝试所有排列更好的方法。
如果您有超过 30 美元的商品,您可以省略它们。
如果您想要某个标准的“最佳”选项,将会有一些改进。
【讨论】:
省略项目是个好主意。不幸的是,在实际情况下,我正在处理交易时间,因此在某个地方,参与更大的转变可能是一项功能。不过这可以分开处理,你想想……【参考方案4】:这个问题其实是P/NP。例如,如果没有强力搜索,您可能无法找到最合适的商品价格,并且如果您的客户商店很大 - 您会发现该搜索非常持久。
你可以使用一些可以给你很好猜测的现有算法,但我担心它们都是非 SQL 的。
我建议对您的问题进行近似:
创建过程/查询以找到最适合所需价格的一篇文章,然后再次调用它以获得新的更改。不完美,但可以胜任。
【讨论】:
以上是关于MySQL 查找小计的主要内容,如果未能解决你的问题,请参考以下文章