对SQL语句不熟悉欢迎查看我整理的笔记:[SQL] MySQL基础 + python交互
转载请注明:陈熹 chenx6542@foxmail.com (简书号:半为花间酒)
若公众号内转载请联系公众号:早起Python
题目:
简单题 #181
SQL架构:
Create table If Not Exists Employee (Id int, Name varchar(255), Salary int, ManagerId int);
Truncate table Employee;
insert into Employee (Id, Name, Salary, ManagerId) values ('1', 'Joe', '70000', '3');
insert into Employee (Id, Name, Salary, ManagerId) values ('2', 'Henry', '80000', '4');
insert into Employee (Id, Name, Salary, ManagerId) values ('3', 'Sam', '60000', 'None');
insert into Employee (Id, Name, Salary, ManagerId) values ('4', 'Max', '90000', 'None');
题解:
XX和XX比的基本思想是将比较的二者放在同一行
限制条件有两个:
- 员工的
ManagerId
是经理的Id
- 员工的
Salary
超过对于经理的Salary
- 第一种解法
—— 基于笛卡尔积的连表
SELECT a.Name AS Employee
FROM Employee AS a,Employee AS b
WHERE a.ManagerId = b.Id
AND a.Salary > b.Salary
解法很直接,实际上就是自连接
从自己分为两个表以后用WHERE
将两个限制条件表述出来
注意这里两表相连是笛卡尔积
如果数据量大时需要优化
- 第二种解法
—— 基于JOIN
的连表
SELECT a.name as Employee
FROM Employee a
LEFT JOIN Employee b ON a.ManagerId = b.id
WHERE a.salary > b.salary
这里使用LEFT JOIN
根据Id
和ManagerId
完成自连接,再用salary
判别即可
效率会超过笛卡尔积连表
- 第三种解法
—— 基于WHERE
里的半连接
SELECT Name Employee
FROM Employee E
WHERE Salary >
(
SELECT Salary FROM Employee WHERE Id = E.ManagerId
)
半连接的特点是建立的子查询是动态的,需要利用查询外部的条件
SQL的运算是逐行匹配,每次运行都将当前行的ManagerId
传入子查询再和Salary
用WHERE
比对大小即可
半连接思路很巧妙,可以巧妙化解分组聚合问题,但:
能连表则尽量不要用子查询,因为效率一般不高