【问题标题】:How do I compare 2 fields and return the lowest value of each record?如何比较 2 个字段并返回每条记录的最小值?
【发布时间】:2011-01-16 08:41:46
【问题描述】:

我正在慢慢学习如何为我父母的企业创建一个产品和供应商数据库。我得到的是一个由我们的产品参考索引的产品表,以及 2 个不同供应商的另外 2 个表,其中包含与我们的参考链接的供应商产品参考和价格。

我进行了一个执行左外连接的查询,以便它返回我们的产品表,其中包含每个供应商的参考和价格,即:

参考 |产品名称 |供应商 1 参考 | 供应商 1 价格 |供应商 2 参考 | 供应商 2 价格

这是我使用的查询:

SELECT Catalog.Ref, Catalog.[Product Name], Catalog.Price, 
    [D Products].[Supplier Ref], [D Products].Cost, 
    [GS Products].[Supplier Ref], [GS Products].Cost

FROM ([Catalog] LEFT JOIN [D Products] ON Catalog.Ref = [D Products].Ref)

LEFT JOIN [GS Products] ON Catalog.Ref = [GS Products].Ref;

并非所有产品都可从两家供应商处获得,因此采用外连接。

我想做的(通过查询?)是获取上面查询生成的表格,并简单地显示产品参考、最便宜的供应商参考和最便宜的供应商价格,即:

参考 |最便宜的供应商参考 | 最便宜的供应商价格

不幸的是,我的 SQL 知识还不足以解决这个问题,但如果有人能提供帮助,我将不胜感激。

谢谢,罗伯

【问题讨论】:

  • 你能告诉我们产生最高结果的查询吗?以便我们可以适当地修改?

标签: sql database ms-access


【解决方案1】:

请考虑使用一个表格来保存您的供应商产品成本数据。使用此示例 product_catalog 数据:

product_id product_name price
         1 foo              5
         2 bar             10
         3 baz             15

供应商表可能如下所示:

supplier_id product_id cost
D                    1 2.5
D                    2 7.5
GS                   1 2.75
GS                   3 10

然后 GROUP BY 查询 qryLowestPrice 将显示每种产品的最低成本:

SELECT s.product_id, Min(s.cost) AS MinOfcost
FROM suppliers AS s
GROUP BY s.product_id;

然后您可以在另一个查询中使用 qryLowestPrice 来提取您想要的其他信息(产品名称和供应商 ID):

SELECT q.product_id, p.product_name, p.price, s.supplier_id, s.cost
FROM
    (qryLowestPrice AS q
    INNER JOIN product_catalog AS p
    ON q.product_id = p.product_id)
    INNER JOIN suppliers AS s
    ON (q.MinOfcost = s.cost) AND (q.product_id = s.product_id);

这是基于上述示例数据的第二个查询的输出:

product_id product_name price supplier_id cost
         1 foo              5 D           2.5
         2 bar             10 D           7.5
         3 baz             15 GS          10

【讨论】:

  • 效果很好,伙计,非常感谢你,你帮我省了很多麻烦!
【解决方案2】:

试试这个

SELECT  Catalog.Ref, 
        Catalog.[Product Name], 
        Catalog.Price, 
        [D Products].[Supplier Ref], 
        [D Products].Cost, 
        [GS Products].[Supplier Ref], 
        [GS Products].Cost,
        iif ([D Products].Cost < [GS Products].Cost, [D Products].[Supplier Ref], [GS Products].[Supplier Ref]) AS CheapestSupplier,
        iif ([D Products].Cost < [GS Products].Cost, [D Products].Cost, [GS Products].Cost) AS CheapestSupplierPrice
FROM (  [Catalog] LEFT JOIN 
        [D Products] ON Catalog.Ref = [D Products].Ref) LEFT JOIN 
        [GS Products] ON Catalog.Ref = [GS Products].Ref;

【讨论】:

  • 这似乎很好用,谢谢约翰,但我注意到,如果产品存在于 [GS 产品] 中,那么两个最便宜的列只会返回值,例如,如果产品仅在 [D 产品] 中可用] table 它不会在最便宜的列中显示任何内容,但如果它仅在 [GS Products] 表或两个表中可用,它确实有效。有什么建议吗?
  • 我使用嵌套 iif 检查每个字段是否为空,然后运行价格比较,谢谢约翰
  • 我正要回答,MSSQL 有一个名为 ISNULL(column, value) 的函数,其中 column 是您的列,value 是您想要返回的值(如果它为空)。在访问中,我认为它是 nz(column,value)。基本上,如果该列为空,则返回值,否则返回列。
  • 如果 D 和 GS 都为给定产品提供相同的成本,则查询将返回 GS 成本。如果 D 提供了 GS 不提供的产品,则查询将返回 GS 成本(Null)。如果 @BigRob 需要处理超过 2 个供应商,则 IIf() 逻辑将变得更具挑战性。
  • 在 Access/Jet/ACE Nz() 中相当于 SQL Server IsNull()。
【解决方案3】:

我认为您会希望以最低的价格获得相应的供应商参考。可以使用CASE WHEN 构造来完成:

CASE WHEN expression THEN true_part ELSE false_part END

会是:

SELECT Ref,
  CASE WHEN Supplier1Price < Supplier2Price THEN Supplier1Ref ELSE Supplier2Ref END AS "Cheapest Supplier Ref",
  CASE WHEN Supplier1Price < Supplier2Price THEN Supplier1Price ELSE Supplier2Price END AS "Cheapest Supplier Price"

当您使用 Access 时,语法会有所不同。可以使用IIF(condition, true_part, false_part)函数。

SELECT Ref,
  IIF(Supplier1Price < Supplier2Price, Supplier1Ref, Supplier2Ref) AS "Cheapest Supplier Ref",
  IIF(Supplier1Price < Supplier2Price, Supplier1Price, Supplier2Price) AS "Cheapest Supplier Price"

【讨论】:

  • 谢谢你的回答,伙计,你所说的对我来说很有意义,但访问不喜欢我的语法:SELECT [Products Query].[Ref], CASE WHEN [GS Products].[ Cost]
  • 在 Access 中,您必须使用 IIF。我已经用示例更新了我的回复
  • 再次感谢您的回复,但我仍然在使用 Access 时遇到问题,现在它返回“查询表达式中函数使用的参数数量错误”MIN([GS Products].Cost, [ D产品].Cost)
  • 你说得对,我滥用了Min 函数,因为它是一个聚合器。使用与另一个相同的构造 IIF
  • 您可能必须将 null 转换为 as 值。当字段为空时,尝试COALESCE(field, default_value)ISNULL(field, default_value) 将字段中的值替换为default_value
猜你喜欢
  • 2016-10-19
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多