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

相关推荐
全栈老石2 小时前
拆解低代码引擎核心:元数据驱动的"万能表"架构
数据库·低代码
倔强的石头_21 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤3 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区4 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
加号35 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏5 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐5 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再5 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip