gpt4 book ai didi

mysql - 具有复合连接条件的 SQL LEFT JOIN 如何工作

转载 作者:行者123 更新时间:2023-11-28 23:24:58 25 4
gpt4 key购买 nike

假设我想选择包含列分组最大值的行,如本文 http://dev.mysql.com/doc/refman/5.7/en/example-maximum-column-group-row.html 中所述.它确实解决了问题。但是我不明白最后一个解决方案是如何工作的。如果我执行了描述的所有步骤,我会得到想要的结果:

CREATE TABLE shop (
article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
dealer CHAR(20) DEFAULT '' NOT NULL,
price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
PRIMARY KEY(article, dealer));

INSERT INTO shop VALUES
(1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
(3,'C',1.69),(3,'D',1.25),(4,'D',19.95);

SELECT s1.*
FROM shop s1
LEFT JOIN shop s2 ON s1.article = s2.article AND s1.price < s2.price
WHERE s2.price IS NULL;

+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
| 0001 | A | 3.45 |
| 0001 | B | 3.99 |
| 0002 | A | 10.99 |
| 0003 | B | 1.45 |
| 0003 | C | 1.69 |
| 0003 | D | 1.25 |
| 0004 | D | 19.95 |
+---------+--------+-------+

但我不明白这个结果是如何使用 LEFT JOIN 获得的和复合连接条件。如果我在没有 WHERE 的情况下尝试相同的查询子句,我明白了:

SELECT *
FROM shop s1
LEFT JOIN shop s2 ON s1.article = s2.article AND s1.price < s2.price;

+---------+--------+-------+---------+--------+-------+
| article | dealer | price | article | dealer | price |
+---------+--------+-------+---------+--------+-------+
| 0001 | A | 3.45 | 0001 | B | 3.99 |
| 0001 | B | 3.99 | NULL | NULL | NULL |
| 0002 | A | 10.99 | NULL | NULL | NULL |
| 0003 | B | 1.45 | 0003 | C | 1.69 |
| 0003 | C | 1.69 | NULL | NULL | NULL |
| 0003 | D | 1.25 | 0003 | B | 1.45 |
| 0003 | D | 1.25 | 0003 | C | 1.69 |
| 0004 | D | 19.95 | NULL | NULL | NULL |
+---------+--------+-------+---------+--------+-------+

显然,第一个查询只获取了具有 NULL 的行s 恰好包含所需的值。不太清楚的是某些不满足连接条件的行如何包含在结果集中并具有 NULL s 在其中,而另一行根本不包括在内。如果我删除 s1.price < s2.price条件结果如下所示:

SELECT *
FROM shop s1
LEFT JOIN shop s2 ON s1.article = s2.article;

+---------+--------+-------+---------+--------+-------+
| article | dealer | price | article | dealer | price |
+---------+--------+-------+---------+--------+-------+
| 0001 | A | 3.45 | 0001 | A | 3.45 |
| 0001 | A | 3.45 | 0001 | B | 3.99 |
| 0001 | B | 3.99 | 0001 | A | 3.45 |
| 0001 | B | 3.99 | 0001 | B | 3.99 |
| 0002 | A | 10.99 | 0002 | A | 10.99 |
| 0003 | B | 1.45 | 0003 | B | 1.45 |
| 0003 | B | 1.45 | 0003 | C | 1.69 |
| 0003 | B | 1.45 | 0003 | D | 1.25 |
| 0003 | C | 1.69 | 0003 | B | 1.45 |
| 0003 | C | 1.69 | 0003 | C | 1.69 |
| 0003 | C | 1.69 | 0003 | D | 1.25 |
| 0003 | D | 1.25 | 0003 | B | 1.45 |
| 0003 | D | 1.25 | 0003 | C | 1.69 |
| 0003 | D | 1.25 | 0003 | D | 1.25 |
| 0004 | D | 19.95 | 0004 | D | 19.95 |
+---------+--------+-------+---------+--------+-------+

据我所知,INNER JOIN它是这样工作的:首先执行交叉连接,然后根据连接条件过滤结果。对于外部连接,我不确定。所以我不明白为什么,例如,像

这样的行
|    0001 | A      |  3.45 |    0001 | A      |  3.45 |

完全不包含在先前查询的结果集中(即当添加 s1.price < s2.price 时)而

|    0001 | B      |  3.99 |    0001 | A      |  3.45 |

包含在 NULL 中在他们的下半场。那么有人可以解释 SQL JOIN 的行为吗?是吗?

最佳答案

通过使用左联接,您始终可以从左表(在您的例子中为 s1)中获取所有行。当 ON 子句条件匹配来自 s1 的特定行时,连接结果将包含它与 s2 匹配的次数之后 where 条件适用于结果集(如果有的话)

你还应该记住,如果至少有一个参数为 NULL,条件运算符如 =、> 总是返回 false

所以行

|    0001 | A      |  3.45 |    0001 | A      |  3.45 |

未添加,因为它与您的条款不匹配 s1.price < s2.price

以及行

|    0001 | B      |  3.99 |    0001 | A      |  3.45 |

添加,仅当您不检查价格时,如s1.price < s2.price,仅使用文章加入。

关于mysql - 具有复合连接条件的 SQL LEFT JOIN 如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39755435/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com