在 MS Access 中从产品 ID 查找成本

Find Cost from Product ID in MS Access

我正在尝试在 MS Access 中为订单的 "Total Cost" 创建一个计算字段。我的表格如下相关:

所以我希望能够将订单:成本设置到一个计算字段,它获取与每个项目 1、2、3、4 和 5 的关联并将它们加在一起。

另外,有没有更灵活的方法可以在没有多个项目列的情况下向每个订单添加多个产品?

提前致谢!

(我对此很陌生,如果我遗漏了任何重要内容,我深表歉意)

目前,您的设计不是"normalized"。

你的 table "orders" 应该分成两个 table,像这样:

Table "Orders":

  • 订单编号
  • 订购日期
  • 成本(此字段有什么用?)

Table "Ordered Items":

  • 订单编号
  • 产品编号

因此,"Ordered Items" 可以包含无限数量的订购商品。然后您可以非常轻松地创建任何类型的总和和其他计算。

apologies if I've missed out anything critical

你做到了。您必须规范化您的数据(bing/google)- 插入一个 table 保存订单行。然后您将在订单 table 和订单行与产品之间建立一种关系。

你的设计是错误的。我建议您阅读一些有关 database normalisation 的教程并更正您的设计。
您还可以 locate/download 臭名昭著的 Northwind 数据库,该数据库曾经作为示例与 Access 一起提供。这是一个可用且设计合理的订单数据库,您可以将其用作起点。

正如其他人强调的那样,您的 table 的结构存在根本问题。为了回答您的问题,我建议您先调整 table 模式。

因此我先回答你的第二个问题:

is there a more flexible way to add multiple products to each order without having multiple item columns?

是的。通常,您需要使用第二个 table 来存储您的订单商品。这种类型的 table 通常称为 'bridge table',它可以让您存储无限数量的商品对于每个订单。我们称之为 table Order Items.

顺便说一句,我假设您的 tables 产品,Products_1、Products_2、Products_3 和 Products_4 都是与一样table?而不是 5 table 全部包含您的产品数据的副本。我稍后会回来讨论这个。

让我们将您的 table 重组为如下所示:

注意我们的新桥 table Order Items。要在此处存储订单项目,只需为订单包含的每个产品创建一条记录,并引用产品 ID 和关联的订单 ID。

示例订单

数据

Orders table:

+----------+------------+------+
| Order ID | Order Date | Cost |
+----------+------------+------+
|        1 | 2015-04-25 | —    |
+----------+------------+------+

注意:暂时忽略成本字段。我稍后会讲到。

Order Items table:

+----------+------------+
| Order ID | Product ID |
+----------+------------+
|        1 |          2 |
|        1 |          3 |
|        1 |          5 |
+----------+------------+

Products table:

+------------+---------+------+-------+
| 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 桥 table,我们能够以更灵活的格式存储有关订购产品的信息。与您的原始数据库架构相比,这样做的一大优势是您不再局限于每个订单 5 件商品。

现在,如果我之前关于多个产品 tables 的假设是 错误的 ,那么这个新架构将为您提供额外的优势,因为您将不再需要在 5 table 秒内复制您的产品数据。您永远不必在数据库中复制数据 - 目标是始终拥有 'single source of truth'。因此,您的产品数据应该只存储在一个地方,并且 永远不会 复制到多个 table 中。

这就是您所说的 'normalised' 数据库架构。

那么成本计算如何?

好吧,我不得不承认,我不是 MS Access 专家。我对 MySQL 有更多的经验。所以我会尽力提供帮助。

首先 - 我在这里所说的一切都将基于我上面提出的新 table 结构。原始 table 结构的成本计算会有所不同(并且可能更复杂!)

使用数据库的优点之一是您可以动态查询和对数据执行计算。一种这样的计算是总订单成本。 MS Access 将提供一项功能,可以根据相关产品的价格动态计算订单的总成本。由于可以动态计算,因此您无需将此值存储在数据库中。

还记得我之前所说的在你的数据库中有一个 'single source of truth' 吗?这也适用于此。无需存储计算出的订单总额,因为每次更改订单项目时您最终都必须重新计算。这将是多余的,因为它可以通过 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 ItemsOrder Items -> Products.

总而言之 - 尽管您已经在正确的轨道上,但您需要稍微更改数据库结构。新的数据库结构已规范化,可让您执行查找并轻松计算总订单成本。

希望对您有所帮助。


后续步骤(可选)

解决了基本问题后,您可能会对更进一步感兴趣。

您可能忽略的一件事是人们可以订购多个相同的产品。以我上面的例子为例,如果我们想要 2 条围巾 而不是 1 条怎么办?目前无法为订单中的每个产品存储数量。

您需要做的是在 Order Items table 中添加一个 Quantity 字段。因此,我们的新示例订单商品 table 将如下所示:

Order Items table:

+----------+------------+----------+
| Order ID | Product ID | Quantity |
+----------+------------+----------+
|        1 |          2 |        2 |
|        1 |          3 |        1 |
|        1 |          5 |        1 |
+----------+------------+----------+

由此可以看出订单中包含2条围巾、1副手套、1双靴子。

用数量计算总数

这个新的数量字段需要更改您计算订单总成本的方式。我们现在需要计算数量 × 产品价格,并将它们加在一起得到订单总数。

This SO post may be of some help for this. 本质上,您需要使用如下内容(未测试!):

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(美元/英镑/等)。如果在我下订单后产品价格上涨,我们将不再有下订单时支付价格的记录。

我觉得我现在跳得很远,所以我会把它留给你考虑。如果您需要这方面的帮助,您可能应该 post 一个新问题。