数据分析|SQL牛客网刷题(一)——1、2、3、17、18题解析

Excel的题目很多,但大多和数据分析不太沾边,Power BI的题目就更少了,所以我只能看到什么做什么了,估计分享在知乎上的excel题目解析也不会太多。Power BI这块后续有适合分析的案例我会使用Power BI做Dashboard,应该会涉及到一些Power BI的使用讲解。
市面上比较推荐的SQL和python刷题网站分别是leetcode和牛客,因为leetcode的题目实在太多,有点累心,还是现在看起来可以更快完成的牛客开始。
【SQL1. 查找最晚入职员工的所有基本信息】
题目描述:

查找最晚入职员工的所有信息,为了减轻入门难度,目前所有的数据里员工入职的日期都不是同一天(sqlite里面的注释为--,mysql为comment)
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL, -- '员工编号'
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
代码:
select * from employees where hire_date= (select max(hire_date) from employees);

思路:
最晚入职员工及hire_date最大的员工,先查询出employees表中hire_date的最大值作为子查询,外面再嵌套一次查询,用where作为筛选条件,即可得出结果:
数据分析|SQL牛客网刷题(一)——1、2、3、17、18题解析
文章图片

【SQL2. 查找入职员工时间排名倒数第三的员工所有信息】
题目描述:
查找入职员工时间排名倒数第三的员工所有信息,为了减轻入门难度,目前所有的数据里员工入职的日期都不是同一天
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
代码:
select * from employees order by hire_date desc limit 1 offset 2;

思路:
按hire_date降序排序,排位第一的数据就是入职最晚的人,使用limit函数限制输出一条数据,再用offset偏移两个数据,得到排名第三的数据,结果如下:
数据分析|SQL牛客网刷题(一)——1、2、3、17、18题解析
文章图片

【SQL3. 查找当前薪水详情以及部门编号】
题目描述:
查找各个部门当前(dept_manager.to_date='9999-01-01')领导当前(salaries.to_date='9999-01-01')薪水详情以及其对应部门编号dept_no
(注:请以salaries表为主表进行查询,输出结果以salaries.emp_no升序排序,并且请注意输出结果里面dept_no列是最后一列)
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL, -- '员工编号',
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL, -- '部门编号'
`emp_no` int(11) NOT NULL, -- '员工编号'
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
代码:
select s.*, dept_no from salaries as s join dept_manager as d on s.emp_no=d.emp_no where s.to_date='9999-01-01' and d.to_date='9999-01-01' order by s.emp_no;

思路:
这题设计两表连接,相同字段就是emp_no字段,本体的逻辑是只查询经理的薪资,所以我们采用内连接inner join(mysql中inner可以省略),结果如下:
数据分析|SQL牛客网刷题(一)——1、2、3、17、18题解析
文章图片

前面三道都是“中等”难度的题目,但是实际上对应leetcode的难度的话,其实是在简单难度以下的,后面我们再来做两道“较难”难度的题目。
【SQL17. 获取当前薪水第二多的员工的emp_no以及其对应的薪水salary】
问题描述:
获取当前(to_date='9999-01-01')薪水第二多的员工的emp_no以及其对应的薪水salary
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
代码:
select emp_no, salary from salaries where to_date = '9999-01-01' order by salary desc limit 1 offset 1;

【数据分析|SQL牛客网刷题(一)——1、2、3、17、18题解析】思路:
这个题有点让我哭笑不得,和SQL2题目的解题思路是一样的,唯一复杂点的就是多了一个where语句的筛选,难度甚至还没SQL3高,也能被排到“较难”难度,着实让人摸不着头脑,结果如下:
数据分析|SQL牛客网刷题(一)——1、2、3、17、18题解析
文章图片

【SQL18. 查找当前薪水第二多的员工的emp_no以及其对应的薪水salary】
问题描述:
查找当前薪水(to_date='9999-01-01')排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,你可以不使用order by完成吗
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
代码:
select e.emp_no, max(salary) as salary, last_name, first_name from employees as e join salaries as s on e.emp_no=s.emp_no where to_date='9999-01-01' and salary<( select max(salary) from salaries);

思路:
若没有不使用order by这条的限制,这题其实就是SQL17和SQL3的结合,不使用order by的话,我们就需要使用嵌套查询了。
首先解释一下括号里的部分:
select max(salary) from salaries

其实就是从薪水表中查找薪水的最大值,整个查询结果返回的就是一个值,我们姑且记做a,方便后续理解,用a替换括号里的部分,代码就变成了:
select e.emp_no, max(salary) as salary, last_name, first_name from employees as e join salaries as s on e.emp_no=s.emp_no where to_date='9999-01-01' and salary

where之前就是做了一个多表的内连接,思路可以参考SQL3题,where语句筛选的范围就是to_date符合要求且salary比a小的所有数据,我们再从中筛选出max(salary)对应的所需数据就可以了。换句话说,就说在比最大值小的所有数据里找最大值,即第二大的值,矮子里拔将军的道理,结果如下:
数据分析|SQL牛客网刷题(一)——1、2、3、17、18题解析
文章图片

今天是周六,我也要注意劳逸结合,今天只做了5道题,分别是3道“中等”难度和2道“较难”难度,但是实际上我感觉这些题在leetcode里都只能对应到“简单”难度。但是练习和打怪升级一样,总要先从简单的开始。

    推荐阅读