🎬 HoRain 云小助手:个人主页
⛺️生活的理想,就是为了理想的生活!
⛳️ 推荐
前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。
目录
⛳️ 推荐
💡 关键在于 LEFT JOIN的特性
🧪 通过实例理解
✅ 实用建议与选择
理解JOIN ... ON中多个条件与WHERE子句的区别,对于编写正确和高效的 SQL 查询至关重要。核心差异在于ON子句决定表之间如何连接,而WHERE子句决定最终结果集中包含哪些行。
下面这个表格直观地展示了两者的主要区别。
特性 |
|
|
|---|---|---|
执行时机 | 在连接过程中应用 | 在连接完成后,对中间结果进行过滤 |
主要作用 | 确定右表中哪些行与左表匹配 | 过滤最终结果集,所有不满足条件的行都会被排除 |
对左表行数的影响 | 不影响左表行数,即使右表无匹配,左表行仍会保留(右表字段以 | 会影响最终返回的行数,不满足条件的行(包括左表行)会被过滤掉 |
对结果的影响 | 影响右表匹配内容,不匹配则右表字段为 | 决定最终哪些行可以出现在结果集中 |
💡 关键在于LEFT JOIN的特性
上述区别在LEFT JOIN(左连接)中表现得最为明显。LEFT JOIN的核心承诺是:无论如何都会返回左表的所有行。
条件放在
ON子句:数据库引擎会尝试用左表的每一行去匹配右表中满足ON后所有条件的行。如果找不到匹配的右表行,为了兑现“返回左表所有行”的承诺,它仍然会返回左表数据,同时将右表的所有字段设为NULL。条件放在
WHERE子句:连接过程首先基于基本的ON条件(如A.id = B.id)进行,生成一个包含左表所有行和可能匹配的右表数据的临时结果集。然后,WHERE条件会像筛子一样过滤这个临时结果集。如果一条左表记录对应的右表记录不满足WHERE条件,整条记录都会被筛掉,这可能导致左表记录丢失,从而使LEFT JOIN的效果退化为类似INNER JOIN。
🧪 通过实例理解
我们通过一个具体例子来加深理解。假设有两个表:
product(产品表)id
amount
1
100
2
200
3
300
4
400
product_details(产品详情表)id
weight
exist
2
22
0
4
44
1
5
55
0
场景一:筛选条件在ON子句中
SELECT * FROM product LEFT JOIN product_details ON (product.id = product_details.id AND product_details.id = 2);结果:会返回4行数据。左表product的所有记录都被返回,但只有id=2的产品在product_details中有匹配的详细信息,其他产品的详情字段均为NULL。
product.id | amount | product_details.id | weight | exist |
|---|---|---|---|---|
1 | 100 | NULL | NULL | NULL |
2 | 200 | 2 | 22 | 0 |
3 | 300 | NULL | NULL | NULL |
4 | 400 | NULL | NULL | NULL |
场景二:筛选条件在WHERE子句中
SELECT * FROM product LEFT JOIN product_details ON (product.id = product_details.id) WHERE product_details.id = 2;结果:只返回1行数据。这条查询先进行左连接,产生一个包含4行记录的中间表,然后WHERE条件product_details.id = 2会过滤掉所有右表id不是2或为NULL的行,最终只保留id=2的产品记录。
product.id | amount | product_details.id | weight | exist |
|---|---|---|---|---|
2 | 200 | 2 | 22 | 0 |
✅ 实用建议与选择
了解区别后,如何做出正确选择呢?
当你需要保留左表的所有记录时
使用
LEFT JOIN ... ON,并将对右表的过滤条件放在ON子句中。这在需要统计左表主数据的存在情况时非常有用,例如“查询所有产品及其审核状态(即使某些产品尚未被审核)”。当你需要过滤最终结果集时
使用
WHERE子句。例如,当你明确只需要“存在特定详情的产品”信息时。关于对左表自身的过滤
对于左表本身的过滤条件(例如
product.amount > 150),放在ON或WHERE子句对结果集行数的影响是相同的。但出于清晰和性能考虑,建议始终放在WHERE子句中,因为WHERE是标准的对结果集进行过滤的地方。INNER JOIN的特殊情况在
INNER JOIN中,由于它只返回两个表都能匹配上的行,将过滤条件放在ON子句还是WHERE子句,最终的结果集通常是一样的。但从语义清晰和优化器理解的角度,最佳实践是:在
ON子句中只放置表之间的关联条件(如A.id = B.id)。在
WHERE子句中放置所有的业务过滤条件(如B.status = 'active')。
希望这些解释和示例能帮助你彻底理解这两者的区别。如果你有具体的查询场景不确定如何设计,可以分享出来,我们一起分析。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙