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 细节的掌握。

相关推荐
Swift社区2 小时前
SQL 执行异常排查 java.sql.SQLException:从 SQLException 说起
java·数据库·sql
qq_417908442 小时前
com.mysql.cj.jdbc.Driver 解析
数据库·mysql
胡斌附体3 小时前
springbatch使用记录
数据库·接口·shell·命令·批量·springbatch·并发抽取
java水泥工5 小时前
网上摄影工作室|基于SpringBoot和Vue的网上摄影工作室(源码+数据库+文档)
数据库·vue.js·spring boot
jingfeng5145 小时前
MySQL库的操作(ubuntu)
数据库·mysql
奔跑吧邓邓子5 小时前
【C++实战(64)】C++ 邂逅SQLite3:数据库编程实战之旅
数据库·c++·sqlite·实战·sqlite3·数据库编程
Tony Bai11 小时前
【Go开发者的数据库设计之道】07 诊断篇:SQL 性能诊断与问题排查
开发语言·数据库·后端·sql·golang
cpsvps_net11 小时前
VPS服务器锁等待超时处理,如何有效解决数据库性能瓶颈
服务器·数据库·oracle
文火冰糖的硅基工坊14 小时前
[创业之路-653]:社会产品与服务的分类
大数据·数据库·人工智能