SQL 多表查询实用技巧:ON 和 WHERE 的区别速览

在 SQL 面试和实际开发中,多表查询是绕不过去的重点。尤其是 ON 和 WHERE 的区别,很多初学者常常混淆,结果写出的语句逻辑错误,甚至导致数据结果不一致。本文带你快速理清这两者的区别和应用场景,避免踩坑。

一、基础概念回顾

在多表查询中,常见的写法有两种:

  1. 在 JOIN ... ON 中写条件

用于指定两张表之间的连接关系,比如主外键的对应。

  1. 在 WHERE 中写条件

用于对最终结果集再进行筛选,类似于过滤器。

简单来说,ON 是连接条件,WHERE 是结果集过滤条件。

二、ON 与 WHERE 的差异

  1. INNER JOIN 中差异不大

当使用 INNER JOIN 时,无论把条件写在 ON 还是 WHERE 中,结果基本一致。因为内连接本身就是取两表交集部分。

示例:

-- 条件写在 ON

SELECT s.id, s.name, c.course_name

FROM Student s

INNER JOIN Course c ON s.id = c.student_id;

-- 条件写在 WHERE

SELECT s.id, s.name, c.course_name

FROM Student s

INNER JOIN Course c

WHERE s.id = c.student_id;

两者的结果相同。

  1. OUTER JOIN 中差异显著

在 LEFT JOIN 或 RIGHT JOIN 中,ON 和 WHERE 的位置不同,结果可能差别很大。

● 条件写在 ON 中

保证了外连接的特性,比如 LEFT JOIN 会保留左表全部数据,即使右表没有匹配记录。

● 条件写在 WHERE 中

会对结果集进行二次过滤,可能导致外连接退化为内连接。

示例:

-- 条件写在 ON 中(会保留所有学生,即使没有课程)

SELECT s.id, s.name, c.course_name

FROM Student s

LEFT JOIN Course c ON s.id = c.student_id;

-- 条件写在 WHERE 中(只保留有课程的学生,左连接失效)

SELECT s.id, s.name, c.course_name

FROM Student s

LEFT JOIN Course c ON s.id = c.student_id

WHERE c.course_name IS NOT NULL;

第一条语句会保留所有学生;第二条语句会丢掉没有课程的学生,等同于 INNER JOIN。

三、常见面试陷阱

  1. 问:为什么 LEFT JOIN 还写了 WHERE c.col IS NOT NULL,结果和 INNER JOIN 一样?

因为 WHERE 把空值过滤掉了,丢掉了外连接的"补全"功能。

  1. 问:实际项目里该怎么写?

连接条件写在 ON,过滤条件写在 WHERE,语义清晰,不容易混淆。

  1. 问:能否通过 ON 写过滤条件?

可以,但要谨慎。比如 ON c.status = 'active',这意味着只在连接时考虑满足条件的行,不会再保留其他结果。

四、最佳实践总结

ON:定义两表之间的连接关系。

WHERE:在结果集上再做过滤。

INNER JOIN:两者差别不大。

OUTER JOIN:差别显著,容易出错,必须小心。

一句口诀:

"连接写在 ON,过滤放 WHERE,OUTER JOIN 特别注意不要混用。"

五、结语

多表查询是 SQL 的高频考点,也是开发常见的操作。真正理解 ON 和 WHERE 的区别,不仅能避免逻辑 bug,还能在面试中体现你对 SQL 细节的掌握。

相关推荐
科技小花1 小时前
全球化深水区,数据治理成为企业出海 “核心竞争力”
大数据·数据库·人工智能·数据治理·数据中台·全球化
X56612 小时前
如何在 Laravel 中正确保存嵌套动态表单数据(主服务与子服务)
jvm·数据库·python
虹科网络安全3 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
2301_771717214 小时前
解决mysql报错:1406, Data too long for column
android·数据库·mysql
小江的记录本4 小时前
【Kafka核心】架构模型:Producer、Broker、Consumer、Consumer Group、Topic、Partition、Replica
java·数据库·分布式·后端·搜索引擎·架构·kafka
dvjr cloi4 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
dFObBIMmai5 小时前
MySQL主从同步中大事务导致的延迟_如何拆分大事务优化同步
jvm·数据库·python
szccyw05 小时前
mysql如何限制特定存储过程执行权限_MySQL存储过程安全访问
jvm·数据库·python
czlczl200209255 小时前
利用“延迟关联”优化 MySQL 巨量数据的深分页查询
数据库·mysql
ACP广源盛139246256736 小时前
IX8024与科学大模型的碰撞@ACP#筑牢科研 AI 算力高速枢纽分享
运维·服务器·网络·数据库·人工智能·嵌入式硬件·电脑