正如其他人所强调的那样,您的表格的结构方式存在一个根本问题。为了回答您的问题,我建议您先调整表架构。
因此,我将首先回答您的第二个问题:
有没有更灵活的方法可以在每个订单中添加多个产品而无需多个项目列?
是的。通常,您会希望使用第二个表来存储您的订单项目。这种类型的表通常称为“桥表”,它允许您为每个订单存储无限数量的项目。让我们将此表称为Order Items。
顺便说一句,我假设您的表 Products、Products_1、Products_2、Products_3 和 Products_4 都是同一个表的接口?而不是 5 个表都包含您的产品数据的副本。我稍后会回到这个。
让我们重组您的表格,使其看起来像这样:
请注意我们的新桥接表Order Items。要在此处存储订单项目,只需为订单包含的每个产品创建一条记录,并引用产品 ID 和关联的订单 ID。
订单示例
数据
Orders表:
+----------+------------+------+
| Order ID | Order Date | Cost |
+----------+------------+------+
| 1 | 2015-04-25 | — |
+----------+------------+------+
注意:暂时忽略成本字段。待会儿我会讲到的。
Order Items表:
+----------+------------+
| Order ID | Product ID |
+----------+------------+
| 1 | 2 |
| 1 | 3 |
| 1 | 5 |
+----------+------------+
Products表:
+------------+---------+------+-------+
| Product ID | Product | Type | Price |
+------------+---------+------+-------+
| 1 | Hat | — | 5 |
| 2 | Scarf | — | 10 |
| 3 | Gloves | — | 12 |
| 4 | Coat | — | 50 |
| 5 | Boots | — | 25 |
+------------+---------+------+-------+
说明
在上面的示例数据中,订单是在 2015 年 4 月 25 日下达的。订单是 3 个产品:
通过使用Order Items 桥接表,我们能够以更灵活的格式存储有关订购产品的信息。与原始数据库架构相比,它的最大优势在于您不再限于每个订单 5 件商品。
现在,如果我之前关于多个产品表的假设是错误,那么这个新架构将为您带来额外的优势,因为您不再需要跨 5 个表复制产品数据。您永远不必在数据库中复制数据 - 目标是始终拥有“单一事实来源”。因此,您的产品数据应该只存储在一个地方,并且绝不复制到多个表中。
这就是所谓的“规范化”数据库架构。
那么成本计算如何?
我必须承认,我不是 MS Access 专家。我对 MySQL 有更多的经验。所以我会尽量提供帮助。
首先 - 我在这里所说的一切都将基于我上面提出的新表结构。原始表结构的成本计算会有所不同(并且可能更复杂!)
使用数据库的优点之一是您可以动态查询数据并执行计算。一种这样的计算是总订单成本。 MS Access 将提供一项功能,根据相关产品的价格动态计算订单的总成本。由于可以动态计算,因此您无需将此值存储在数据库中。
还记得我之前说过的关于在您的数据库中拥有“单一事实来源”的内容吗?这也适用于此。无需存储计算得出的订单总额,因为每次更改订单商品时,您最终都必须重新计算。这将是多余的,因为它可以由 MS Access 动态计算。
包含订单总额的示例 SQL 查询可能如下所示:
SELECT
`Orders`.*, SUM(`Products`.`price`) AS `Cost`
FROM
`Orders`
LEFT JOIN `Order Items` ON (
`Orders`.`Order ID` = `Order Items`.`Order ID`
)
LEFT JOIN `Products` ON (
`Order Items`.`Product ID` = `Products`.`Product ID`
)
GROUP BY
`Orders`.`Order ID`
这里我使用SUM() 函数来计算与订单相关的所有产品价格的总和。 GROUP BY 运算符用于将与单个订单关联的所有产品集中在一起。当然,这一切都与 2 个连接联系在一起:Orders -> Order Items 和 Order Items -> Products。
总而言之 - 尽管您已经走在正确的轨道上,但您需要稍微改变您的数据库结构。新的数据库结构已标准化,可让您执行查找并轻松计算总订单成本。
希望对您有所帮助。
后续步骤(可选)
一旦你解决了基本问题,你可能有兴趣更进一步。
您可能忽略的一件事是人们可以订购多个相同的产品。以我上面的例子为例,如果我们想要 2 条围巾 在我们的订单中而不是 1 条呢?您目前无法针对订单中的每个产品存储数量。
您需要在Order Items 表中添加一个Quantity 字段。因此,我们的新示例订单商品表将如下所示:
Order Items表:
+----------+------------+----------+
| Order ID | Product ID | Quantity |
+----------+------------+----------+
| 1 | 2 | 2 |
| 1 | 3 | 1 |
| 1 | 5 | 1 |
+----------+------------+----------+
从这里您可以看到订单包含 2 条围巾、1 双手套和 1 双靴子。
用数量计算总计
这个新的数量字段将要求您更改计算总订单成本的方式。我们现在需要做 Quantity × Product Price,然后将它们加起来得到订单总数。
This SO post may be of some help for this. 基本上你会想要使用类似下面的东西(UNTESTED!):
SELECT
`Orders`.*, SUM(`Products`.`price` * `Order Items`.`Quantity`) AS `Cost`
FROM
`Orders`
LEFT JOIN `Order Items` ON (
`Orders`.`Order ID` = `Order Items`.`Order ID`
)
LEFT JOIN `Products` ON (
`Order Items`.`Product ID` = `Products`.`Product ID`
)
GROUP BY
`Orders`.`Order ID`
请注意,我们现在将价格和数量相乘以计算 Cost 字段。
产品价格变化
未来要考虑的另一件事是您的产品价格是否会发生变化。当我的示例订单下达时,手套成本为 12(美元/英镑/等)。如果在我下订单后产品价格上涨,我们将不再有下订单时支付的价格记录。
我觉得我现在已经领先一步了,所以我会把这件事留给你考虑。如果您需要这方面的帮助,您可能应该发布一个新问题。