这是SQL今日一题的第17篇文章
题目描述1
查找员工编号emp_no为10001其自入职以来的薪水salary涨幅(总共涨了多少)growth(可能有多次涨薪,没有降薪)
用到salaries表
salaries表方法1
select MAX(salary) - MIN(salary) as growth
from salaries
where emp_no = 10001
1、where子句给定限定条件,是10001号员工
-
where emp_no = 10001
2、用最大的薪资减去最小薪资得到涨幅
-
MAX(salary) - MIN(salary)
这样的解法不是很严谨,因为默认了该员工现在是涨薪的而不是降薪,所以才能用最大值减去最小值求涨幅,但如果该员工现在被降薪了,那么这个思路就不对了。
方法2
SELECT
(
(
SELECT salary
FROM salaries
WHERE emp_no = 10001
ORDER BY to_date DESC
LIMIT 1
) -
(
SELECT salary
FROM salaries
WHERE emp_no = 10001
ORDER BY to_date ASC
LIMIT 1)
) AS growth
1、第一个子查询按to_date降序取一个salary,也就是取出了最后一次时间记录下的薪水
-
SELECT salary FROM salaries WHERE emp_no = 10001 ORDER BY to_date DESC LIMIT 1
2、第二个子查询按to_date升序取一个salary,就是取出了入职时的薪水
-
SELECT salary FROM salaries WHERE emp_no = 10001 ORDER BY to_date ASC LIMIT 1
3、两个薪水相减(现在的薪水减去入职时的薪水)就是增幅了。
这样写就比较严谨一些,用当前日期下对应的薪水减去入职日期时的薪水,不管当前薪水是涨还是降。
题目描述2
查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序
(注:可能有employees表和salaries表里存在记录的员工,有对应的员工编号和涨薪记录,但是已经离职了,离职的员工salaries表的最新的to_date!='9999-01-01',这样的数据不显示在查找结果里面)
用到salaries表和employees表
salaries表employees表
方法
select s_start.emp_no
,s_now.salary - s_start.salary as growth
from
(
select emp_no
,salary
from salaries
where to_date = '9999-01-01'
) s_now
inner join
(
select s.emp_no
,s.salary
from salaries s
left join employees e on s.emp_no = e.emp_no
where s.from_date = e.hire_date
) s_start
on s_now.emp_no = s_start.emp_no
1、其实和上一题的思路是一样的,查询出每个员工入职时的薪水和当前日期下的薪水相减即可。
2、第一个子查询直接从salaries表中查询当前日期下的薪水,并将这张表命名为s_now表
-
select emp_no,salary from salaries where to_date = '9999-01-01'
3、第二个子查询要连接salaries表和employees表让salaries表中的from_date等于employees表中的hire_date,这样就得到了每个员工入职时的薪水情况,命名为s_start表
-
select s.emp_no,s.salary from salaries s left join employees e on s.emp_no = e.emp_no where s.from_date = e.hire_date
4、将s_now表和s_start表连接起来,并用s_now表的salary 减去s_start表的salary ,就是每个员工薪资的涨幅了。
知识点
子查询
-
子查询可以写在where子句里进行过滤,通常和in结合
-
子查询也可以作为计算字段
注:SQL SERVER里没有limit,可用top替换
@ 作者:可乐
@ 公众号/知乎专栏/头条/简书:可乐的数据分析之路