Mysql多表关联查询时查询条件放在on之后和where之后的区别

Mysql多表关联查询时查询条件放在on之后和where之后的区别

背景

今天在开发中遇到一个问题,在两个表关联查询时,最终得到的结果和预想结果不一致,经过排查后,我发现自己犯了一个很低级的错误,这样会导致查询出来的结果莫名其妙的变多或者变少。

问题重现

准备两张表dept,emp,一张员工表,一张部门表,内容如下;

iddeptName
1交付一部
2交付二部
3交付三部
idempNamedeptIdsalary
1张三12000
2李四12500
3王五23400
4赵六33500

情况一

查询每个部门工资小于3500的员工人数

问题sql:

SELECT
	t.deptName 部门名称,
	count( p.empName ) 部门人数 
FROM
	dept t
	LEFT JOIN emp p ON t.id = p.deptId 
WHERE
	p.salary < 3500 
GROUP BY
	t.deptName

错误结果:

部门名称部门人数
交付一部2
交付二部1

这是因为右表的过滤条件放在where中会被过滤掉,而不会显示0条

正确写法:

SELECT
	t.deptName 部门名称,
	count( p.empName ) 部门人数 
FROM
	dept t
	LEFT JOIN emp p ON t.id = p.deptId and p.salary < 3500
GROUP BY
	t.deptName

正确结果:

部门名称部门人数
交付一部2
交付二部1
交付三部0

情况二

查询每个部门工资小于3500的员工人数(除了交付一部外)

问题sql:

SELECT
	t.deptName 部门名称,
	count( p.empName ) 部门人数 
FROM
	dept t
	LEFT JOIN emp p ON t.id = p.deptId and p.salary < 3500 and t.deptName != '交付一部'
GROUP BY
	t.deptName

错误结果:

部门名称部门人数
交付一部0
交付二部1
交付三部0

这是因为left join 做连接时,左表会显示全部数据,哪怕匹配不上为null的数据,左表过滤应当放入where条件中

正确写法:

SELECT
	t.deptName 部门名称,
	count( p.empName ) 部门人数 
FROM
	dept t
	LEFT JOIN emp p ON t.id = p.deptId and p.salary < 3500 
where t.deptName != '交付一部'
GROUP BY
	t.deptName

正确结果:

部门名称部门人数
交付二部1
交付三部0

总结

在left join 中,左表过滤必须放在where中,右表过滤必须放在on后面,这样结果才能跟我们预想的结果一样,如果是inner join的话,放在on后面和where后面是一样的效果。

posted @   JamieChyi  阅读(126)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2021-12-05 从零开始搭建自己的个人博客 ---> 手把手教你搭建自己的炫酷博客
2021-12-05 爱心宠物诊所管理系统
点击右上角即可分享
微信分享提示