数据分析岗位面试的过程中常考的高频73题刷题笔记,不足之处望多多指正。
前言
无论是在数据分析师面试还是数据挖掘等的多数大数据岗位的面试、工作过程中,SQL都是比较重要的一部分,本文主要是笔者刷牛客的高频73题时的一些笔记整理,欢迎和笔者一起交流讨论。
面试题
SQL1:查找最晚入职员工的信息
- 试题内容:查找最晚入职员工的所有信息,为了减轻入门难度,目前所有的数据里员工入职的日期都不是同一天(sqlite里面的注释为–,mysql为comment)
CREATE TABLEemployees
(
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
));
分析:题目难度:简单
主要考察where条件查询,需要注意的case是最晚入职的员工对应的最大的hire_date,同时也考虑使用order+limit实现最晚员工的找寻。
知识点;ORDER BY field1 [ASC [DESC][默认 ASC]], [field2…] [ASC [DESC][默认 ASC]] (desc降序排列,asc是升序排列) SELECT * FROM table LIMIT a,b;从a+1行开始a+b行结束。
- SQL实现:
思路1
SELECT * FROM employees order by hire_date desc limit 0,1
思路2
SELECT *
FROM employees
WHERE hire_date =
(
SELECT MAX(hire_date)
FROM employees
)
SQL2:查找入职员工时间排名倒数第三的员工所有信息
- 例题:查找入职员工时间排名倒数第三的员工所有信息,为了减轻入门难度,目前所有的数据里员工入职的日期都不是同一天
CREATE TABLEemployees
(
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
));
思路:找到入职时间倒数第三可以使用排序order by倒数第三是倒序第3个,可以用limit或者offset
- SQL实现
# 思路1
select *
from employees
order by hire_date desc
limit 2,1
#知识点limit的用法
# 思路2
SELECT * FROM employees
ORDER BY hire_date DESC
LIMIT 1 offset 2;
SQL3:查找各个部门当前领导当前薪水详情
- 例题:查找各个部门当前(dept_manager.to_date=‘9999-01-01’)领导当前(salaries.to_date=‘9999-01-01’)薪水详情以及其对应部门编号dept_no
(注:输出结果以salaries.emp_no升序排序,并且请注意输出结果里面dept_no列是最后一列)
CREATE TABLEsalaries
(
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 TABLEdept_manager
(
dept_no
char(4) NOT NULL, – ‘部门编号’
emp_no
int(11) NOT NULL, – ‘员工编号’
to_date
date NOT NULL,
PRIMARY KEY (emp_no
,dept_no
));
多表连接加排序问题,笔者在这里遗漏了时间条件发生报错 思路:where条件实先两表连接限制条件+order by实现排序
- SQL实现
select salaries.emp_no, salaries.salary, salaries.from_date, salaries.to_date, dept_manager.dept_no
from dept_manager, salaries
where dept_manager.emp_no=salaries.emp_no
and dept_manager.to_date='9999-01-01'
and salaries.to_date='9999-01-01'
order by salaries.emp_no;
SQL4:查找所有已经分配部门的员工的last_name和first_name
- 题目:查找所有已经分配部门的员工的last_name和first_name以及dept_no(请注意输出描述里各个列的前后顺序)
CREATE TABLEdept_emp
(
emp_no
int(11) NOT NULL,
dept_no
char(4) NOT NULL,
from_date
date NOT NULL,
to_date
date NOT NULL,
PRIMARY KEY (emp_no
,dept_no
));
CREATE TABLEemployees
(
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
));
两表查询取交集问题,已分配部分的员工的逻辑是两表关于emp_no
select employees.last_name,employees.first_name,dept_emp.dept_no
from employees inner join dept_emp
where employees.emp_no=dept_emp.emp_no;
多表查询问题用下图可以帮助比较好的理解记忆:
SQL5:查找所有员工的last_name和first_name以及对应部门编号
“ 问题:查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括暂时没有分配具体部门的员工(请注意输出描述里各个列的前后顺序)
CREATE TABLE dept_emp
(
emp_no
int(11) NOT NULL,
dept_no
char(4) NOT NULL,
from_date
date NOT NULL,
to_date
date NOT NULL,
PRIMARY KEY (emp_no
,dept_no
));
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
));
分析:首先需求字段的last_name与first_name来自员工(employees表)部门编号dept_no来自部门表dept_emp,其次关联字段是emp_no,同时又题目条件:也包括暂时没有分配具体部门的员工可得连接方式为左连接。
- SQL求解:
select employees.last_name
,employees.first_name
,dept_emp.dept_no
from employees left outer join dept_emp
on employees.emp_no=dept_emp.emp_no;
SQL6:查找所有员工入职时的薪水情况
- 问题内容:
查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序(请注意,一个员工可能有多次涨薪的情况)
CREATE TABLEemployees
(
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 TABLEsalaries
(
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
));
分析:条件(1)查询的是员工入职时的工资情况这时应从员工表里获取emp_no和其对应的hire_date在与工资表(salaries的from_date相关联);
条件(2)按emp_no逆序,oeder by xxx dec
- SQL实现
SELECT
e.emp_no,
s.salary
FROM
employees AS e
INNER JOIN salaries AS s
ON e.emp_no = s.emp_no
AND e.hire_date = s.from_date
ORDER BY
e.emp_no DESC
SQL7:查找薪水变动超过15次的员工
有一个薪水表,salaries简况如下:
建表语句如下:
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`));
请你查找薪水变动超过15次的员工号emp_no以及其对应的变动次数t,以上例子输出如下:
思路:需求拆分通过对员工分组并对salary进行去重计数得到每个员工的薪水变化次数,再用where过滤出薪水变动超过15次的员工。
- SQL求解
select emp_no,count(distinct salary) as 't'
from salaries
group by emp_no
having count(distinct salary)>15