【问题标题】:MySQL - selecting the lowest value from a table using JOINMySQL - 使用 JOIN 从表中选择最小值
【发布时间】:2017-11-04 17:06:19
【问题描述】:

以下查询从products 表中选择每个产品线中价格最低的产品:

SELECT 
    a.productline, a.productCode, a.productName, a.buyprice
FROM
    products a
        LEFT JOIN
    products b ON a.productline = b.productline
        AND b.buyprice < a.buyprice
WHERE
    b.productcode IS NULL;

您可以找到代码here。测试代码的在线编辑器是here

我只是无法理解使用表a 中的给定productLine 的查询如何找到最低的buyPrice。对于a 中的某行和某个productLine,表b 中可能有多行。 1)那么如何选择最低的? 2) b.productcode 怎么可能永远是 NULL 作为表 ab 是同一张表?

【问题讨论】:

  • 去掉 WHERE 子句并使用 SELECT * - 然后你会看到 LEFT JOIN 是如何工作的。

标签: mysql join left-join


【解决方案1】:

如果您要在该站点运行此查询:

SELECT 
    a.productline, a.productName, a.buyprice, b.buyprice, b.productName
FROM products a
LEFT JOIN products b ON a.productline = b.productline
        AND b.buyprice < a.buyprice
ORDER BY 
   a.productline, b.buyprice, a.buyprice, b.productName
LIMIT 5

你得到这个结果:

| productline  |             productName             | buyprice | buyprice |             productName             |
|--------------|-------------------------------------|----------|----------|-------------------------------------|
| Classic Cars | 1958 Chevy Corvette Limited Edition |    15.91 | (null)   | (null)                              |
| Classic Cars | 1982 Lamborghini Diablo             |    16.24 | 15.91    | 1958 Chevy Corvette Limited Edition |
| Classic Cars | 1966 Shelby Cobra 427 S/C           |    29.18 | 15.91    | 1958 Chevy Corvette Limited Edition |
| Classic Cars | 1970 Plymouth Hemi Cuda             |    31.92 | 15.91    | 1958 Chevy Corvette Limited Edition |
| Classic Cars | 1961 Chevrolet Impala               |    32.33 | 15.91    | 1958 Chevy Corvette Limited Edition |

因此,如果您查看最右侧的列,您会看到“1958 Chevy Corvette Limited Edition”重复了很多次。这是因为

  1. 将产品表与自身进行比较(这称为“自联接”
  2. 连接条件a.productline = b.productline 表示“Classic Cars”与“Classic Cars”匹配(每个产品线值依此类推),因此将b 中的ALL“Classic Cars”与EACHa 中的“经典汽车”(顺便说一句,你会得到很多很多行)。
  3. 然后,将 a.buyprice 与必须小于 a.buypriceb.buyrice 进行比较。然而,最便宜的汽车(15.91 美元)的匹配行不能低于最便宜的价格,因此LEFT JOIN 允许将不匹配的行包含在结果中,并且所有b 列对于最便宜的汽车行都是 NULL .
  4. 然后where clause 会删除所有b.productcode 具有任何值的行(因为这些行对查找最便宜的a.buyprice 没有兴趣)

因此,当b 中的任何列为空时,只会列出最便宜(最低)的价格

| productline  |             productName             | buyprice | buyprice |             productName             |
|--------------|-------------------------------------|----------|----------|-------------------------------------|
| Classic Cars | 1958 Chevy Corvette Limited Edition |    15.91 | (null)   | (null)                              |

【讨论】:

  • However the cheapest car ($15.91) cannot have a matching row - 如果提到这辆最便宜的车来自表a,那就更容易理解了。
  • AND b.buyprice &lt; a.buyprice WHERE b.productcode IS NULL; - 为什么不能选择最高的buyPrice 而不是最低的?
  • 可以!只需反转谓词以要求价格高于当前行。 (使用 > 而不是
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 2010-10-21
  • 2013-04-03
  • 2011-12-14
相关资源
最近更新 更多