大家好,从今天起我们将对Leetcode中数据库相关题目进行讲解,如果对SQL相关操作还不是很了解的读者可以点击万字Mysql学习笔记复习。


通过做题来学习是最有效的方式,阅读的同时一定要思考每种解法的异同,最好能够敲一遍。

本文为第181题:超过经理收入的员工




01

题目与SQL架构


Create table If Not Exists Employee (Id intName varchar(255), Salary int, ManagerId int);
Truncate table Employee;
insert into Employee (IdName, Salary, ManagerId) values ('1''Joe''70000''3');
insert into Employee (IdName, Salary, ManagerId) values ('2''Henry''80000''4');
insert into Employee (IdName, Salary, ManagerId) values ('3''Sam''60000''None');
insert into Employee (IdName, Salary, ManagerId) values ('4''Max''90000''None');

XX和XX比的基本思想是将比较的二者放在同一行

限制条件有两个:

  • 员工的ManagerId是经理的Id

  • 员工的Salary超过对于经理的Salary


02

第一种解法

基于笛卡尔积的连表


解法很直接,实际上就是自连接,从自己分为两个表以后用WHERE将两个限制条件表述出来,注意这里两表相连是笛卡尔积。

如果数据量大时需要优化

SELECT a.Name AS Employee 
FROM Employee AS a,Employee AS b 
WHERE a.ManagerId = b.Id 
AND a.Salary > b.Salary


03

第二种解法

基于JOIN的连表


这里使用LEFT JOIN根据IdManagerId完成自连接,再用salary判别即可。效率会超过笛卡尔积连表

SELECT a.name as Employee 
FROM Employee a 
LEFT JOIN Employee b ON a.ManagerId = b.id 
WHERE a.salary > b.salary



04

第三种解法

基于WHERE里的半连接


半连接的特点是建立的子查询是
动态的,需要利用查询外部的条件。SQL的运算是逐行匹配,每次运行都将当前行的ManagerId传入子查询再和SalaryWHERE比对大小即可

SELECT Name Employee 
FROM Employee E
WHERE Salary > 
(
SELECT Salary FROM Employee WHERE Id = E.ManagerId 
)

半连接思路很巧妙,可以巧妙化解分组聚合问题,但要注意:能连表则尽量不要用子查询,因为效率一般不高。


©著作权归作者所有:来自51CTO博客作者mb5fe18e32e4691的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 一道Leetcode数据库题的三种解法|文末送书
  2. PHP实现笛卡尔积算法
  3. JavaScript的two-sum问题解法
  4. RxJs分组热观测值的笛卡尔积
  5. 牛客网上的题总结下 python解法

随机推荐

  1. android 获取手机电话号码和短信内容
  2. 第一讲:Android开发环境的搭建
  3. android 纯c/c++开发
  4. android 杀掉进程
  5. listview常用属性记录
  6. Android项目Android Studio目录结构
  7. 【Android 系统开发】 编译 Android文件
  8. registerActivityLifecycleCallbacks 的
  9. Android(java):database disk image is m
  10. Android AudioRecord介绍与Android 6.0后