mysql - SQL 不懂 IN 子句的算法
问题描述
假设您有一个员工表和一个部门表,您需要找到每个部门的最高薪水。
我知道 IN 子句是什么,但不知道这个特定的代码。
我们为什么使用
WHERE (Employee.DepartmentId, Salary) IN
FROM Employee
怎么翻译成通俗的?
- 从这两个表中列出每个部门薪水最高的部门、员工、薪水?(因为它使用分组?)
那么为什么我们不只是在 select 语句的开头使用 max(salary) 呢?最后写 group by 和 order by 而不是写 IN 子句?
SELECT
Department.name AS 'Department',
Employee.name AS 'Employee',
Salary
FROM
Employee
JOIN
Department ON Employee.DepartmentId = Department.Id
WHERE
(Employee.DepartmentId , Salary) IN
( SELECT
DepartmentId, MAX(Salary)
FROM
Employee
GROUP BY DepartmentId
)
解决方案
如果您将其与其他 2 个值进行比较,则类似的表达式WHERE (x,y) IN
是有意义的,例如:
WHERE (x, y) IN ((a,b), (x,y))
等于真的。
IN 子句的右侧可以替换为子查询。
所以你的例子
(Employee.DepartmentId , Salary) IN
( SELECT DepartmentId, MAX(Salary) FROM Employee GROUP BY DepartmentId )
意味着如果员工工资与员工所在部门的最高工资完全匹配,这将匹配。基本上意味着此查询将选择每个部门中的所有最高收入者。
您是对的,可以将其重写为“字段”子句中的子查询,甚至可以作为连接(我的偏好)。
至于利弊。这在很大程度上与习惯和风格有关。人们倾向于重复使用他们习惯的模式,也许作者认为这是最清晰的解决方案。
另一个原因可能是查询速度有多快。你可以自己测量这个。某些查询比其他查询更容易被 mysql 优化。很长一段时间以来,所有 MySQL 子查询都非常慢。
推荐阅读
- javascript - 计算折扣数组
- html - 媒体查询不根据大小变化,总是显示蓝色背景
- ruby - 如何将批处理命令输出分配给 Chef 配方属性
- regex - 正则表达式 url 路径 - 获取特定数字
- openstreetmap - OsmInEdit 的解析器
- python - Django Python 在哪里添加辅助功能不重复代码?
- ios - iOS - 更改 REALM 对象属性时应用程序崩溃
- git - AWS Codebuild - 仅当提交消息包含字符串时才继续构建
- angular - Angular 7 ngOnDestroy 取消订阅不删除订阅
- php - 为什么在 mac catalina 更新后 composer install 会出错?