牛客SQL练习题

之前的综合题有点难度。

这部分是牛客上面的题目,自我总结:

  1. 简单的一次条件限制的可以轻松写出来;
  2. 需要进行嵌套的子查询,逻辑不清;
  3. 有些函数不太知道。

https://www.nowcoder.com/ta/sql

1.查找最晚入职员工的所有信息

使用子查询

# 日期相同也无碍
SELECT * FROM employees
        WHERE hire_date = (SELECT max(hire_date)
FROM employees)
# 只能输出一条
SELECT * FROM employees 
ORDER BY hire_date DESC LIMIT 1;

2.查找入职员工时间排名倒数第三的员工所有信息

先完成子查询,然后根据找到的时间排名,确定该员工所有的信息

# 若存在同一天多人入职,不好使
SELECT
* FROM employees ORDER BY hire_date DESC LIMIT 1 OFFSET 2;
SELECT * FROM employees 
WHERE hire_date=(
SELECT DISTINCT hire_date 
FROM employees
ORDER BY hire_date DESC LIMIT 1 OFFSET 2
);

3.查找当前薪水详情以及部门编号dept_no

只使用where

使用内连接

使用右连接

select salaries.emp_no,salary,from_date,salaries.to_date,dept_no 
from salaries,dept_manager
where salaries.emp_no = dept_manager.emp_no
and dept_manager.to_date='9999-01-01'
and salaries.to_date='9999-01-01'
order by salaries.emp_no;
select s.*,d.dept_no
from salaries as s inner 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';
select s.*,d.dept_no
from salaries as s right join dept_manager as d
on s.emp_no = d.emp_no

4.查找所有已经分配部门的员工的last_name和first_name以及dept_no

右连接

select e.last_name,e.first_name,d.dept_no
from employees as e right join dept_emp as d
on e.emp_no = d.emp_no;

5.查找所有员工的last_name和first_name以及对应部门编号dept_no

左连接

select e.last_name,e.first_name,d.dept_no
from employees as e left join dept_emp as d
on e.emp_no = d.emp_no;

7.查找薪水记录超过15次的员工号emp_no以及其对应的记录次数t

count函数,分组group by

HAVING语句在GROUP BY语句之后;SQL会在分组之后计算HAVING语句

select emp_no,count(distinct from_date) as t
from salaries
group by emp_no
having t>15;

8.找出所有员工当前薪水salary情况

select distinct(salary) 
from salaries
order by salary desc;

10.获取所有非manager的员工emp_no

not in

子查询

select emp_no
from employees
where emp_no not in (select emp_no from dept_manager);

左连接

is null

select e.emp_no
from employees as e
left join dept_manager as d
on e.emp_no=d.emp_no
where dept_no is null;

11.获取所有员工当前的manager

select dept_emp.emp_no, dept_manager.emp_no manager
from dept_emp ,dept_manager
where dept_emp.dept_no = dept_manager.dept_no
and dept_emp.emp_no <> dept_manager.emp_no

☆12.获取每个部门中当前员工薪水最高的相关信息(难)

内连接,外表,内表查询每个部门工资最高的

外表与内表,固定部门

select d.dept_no,d.emp_no,s.salary
from dept_emp as d inner join salaries as s
on d.emp_no = s.emp_no
where s.salary in (
select max(s2.salary)
from dept_emp as d2
inner join salaries as s2
on d2.emp_no = s2.emp_no
and d2.dept_no = d.dept_no #最高薪水,员工表连接
)
order by d.dept_no;

15.查找employees表emp_no与last_name的员工信息

select *
from employees
where emp_no % 2 = 1 and last_name != 'Mary'
order by hire_date desc
select *
from employees
where MOD(emp_no, 2)=1 and last_name != 'Mary'
order by hire_date desc

16.统计出当前各个title类型对应的员工当前薪水对应的平均工资

select title,avg(s.salary)
from titles as t join salaries as s
on t.emp_no = s.emp_no
group by title
order by avg(s.salary)

17.获取当前薪水第二多的员工的emp_no以及其对应的薪水salary

子查询

select emp_no,salary
from salaries
where salary=(
    select distinct salary
    from salaries
    order by salary desc
    limit 1,1 # 第二名
)

18.获取当前薪水第二多的员工的emp_no以及其对应的薪水salary(不能使用order by)

先找出去除第一后的最大值,子查询

去除第一,子查询

select e.emp_no,salary,last_name,first_name
from employees as e inner join salaries as s
on e.emp_no = s.emp_no
where salary=(
    SELECT max(salary)
    FROM salaries
    WHERE to_date='9999-01-01'
    AND salary<(
        SELECT MAX(salary)
        FROM salaries
        WHERE to_date='9999-01-01'
    )# 去除最大值后的新最大值
)

19.查找所有员工的last_name和first_name以及对应的dept_name

有人没部门,左连接

部门表与部门员工表,一对一,内连接

SELECT e.last_name, e.first_name, b.dept_name
FROM employees AS e
LEFT JOIN (SELECT d.dept_no,d.dept_name,de.emp_no
FROM departments AS d
INNER JOIN dept_emp AS de
ON d.dept_no=de.dept_no
) AS b
ON e.emp_no=b.emp_no;

21.查找在职员工自入职以来的薪水涨幅情况

select b.emp_no,(b.salary-a.salary) as growth
from

(select e.emp_no,s.salary
from employees as e join salaries as s
on e.emp_no = s.emp_no
and e.hire_date = s.from_date) as a #入职时候的工资

inner join

(select e.emp_no,s.salary
from employees as e join salaries as s
on e.emp_no = s.emp_no
where s.to_date = '9999-01-01')as b#离职时候的工资

on a.emp_no=b.emp_no
order by growth

22.统计各个部门的工资记录数

聚合函数group by

连接

行数count

子查询:首先将部门员工关系表与薪水表(有的人不止一条记录)联系起来,每个人属于哪一个部门,几条薪水记录

与部门表联系起来,配对上部门的名字

select de.dept_no,dept_name,t.sum
from departments as de left join

(select s.emp_no,dept_no,count(d.dept_no) as sum
from dept_emp as d join salaries as s
on d.emp_no = s.emp_no
group by dept_no
) as t

on de.dept_no = t.dept_no

23.对所有员工的薪水按照salary降序进行1-N的排名

窗口函数dense_rank(),1,1,1,2······

rank(),1,1,1,4······

row_number(),1,2,3,4······

over ( ) as XXX

select emp_no,salary,dense_rank() over (order by salary desc) as paiming
from salaries
where to_date='9999-01-01'
order by paiming asc,emp_no asc

24.获取所有非manager员工当前的薪水情况

select t.dept_no,t.emp_no,f.salary
from 
(select de.emp_no,de.dept_no
from dept_emp as de right join dept_manager as dep
on de.emp_no != dep.emp_no) as t # 非经理的员工

left join
(select e.emp_no,salary,to_date
from salaries as s inner join employees as e
on e.emp_no = s.emp_no
where s.to_date='9999-01-01') as f

on t.emp_no = f.emp_no

(up这段有问题,!= 这部分有问题,)

select t.dept_no,t.emp_no,s.salary
from 
(select de.emp_no,de.dept_no
from dept_emp as de left join dept_manager as dep
on de.emp_no = dep.emp_no
where dep.emp_no is null) as t # 非经理的员工

inner join employees e on t.emp_no = e.emp_no #部门员工关系表
inner join salaries s on t.emp_no = s.emp_no #薪水表
where s.to_date='9999-01-01'
select dep.dept_no, t.emp_no, s.salary
from(
 select e.emp_no
 from employees e
 left join dept_manager ma on e.emp_no = ma.emp_no
 where ma.emp_no is null # 非经理人员的emp_no
) t
inner join dept_emp dep on t.emp_no = dep.emp_no #部门员工关系表
inner join salaries s on t.emp_no = s.emp_no #薪水表
where s.to_date='9999-01-01'

25.获取员工其当前的薪水比其manager当前薪水还高的相关信息

我的思路:

  • 找出员工薪水
  • 找出经理薪水
  • 通过部门连接员工与经理
  • 筛选工资条件
select *
from 
(select de.emp_no emp_no,de.dept_no
from dept_emp as de left join dept_manager as dep
on de.emp_no = dep.emp_no
where dep.emp_no is null) as t1 # 找出员工

left join

(select de.emp_no manager_no,de.dept_no
from dept_emp as de left join dept_manager as dep
on de.emp_no = dep.emp_no
where dep.emp_no is not null) as t2 # 找出经理

on t1.dept_no=t2.dept_no

10001|d001|10002|d001

select DISTINCT emp_no,manager_no,emp_salary,manager_salary
from
(select t1.emp_no,t1.dept_no,salary emp_salary from
(select de.emp_no emp_no,de.dept_no
from dept_emp as de left join dept_manager as dep
on de.emp_no = dep.emp_no
where dep.emp_no is null) as t1 # 找出员工
inner join salaries as s on t1.emp_no=s.emp_no) m

left join


(select t2.manager_no,t2.dept_no,salary manager_salary from
(select de.emp_no manager_no,de.dept_no
from dept_emp as de left join dept_manager as dep
on de.emp_no = dep.emp_no
where dep.emp_no is not null) as t2# 找出经理
inner join salaries as s on t2.manager_no=s.emp_no) n

on m.dept_no=n.dept_no

where manager_salary<emp_salary

https://www.nowcoder.com/practice/f858d74a030e48da8e0f69e21be63bef?tpId=82&tags=&title=&difficulty=0&judgeStatus=0&rp=1

26.汇总各个部门当前员工的title类型的分配数目

  • 每个员工所在部门+部门名(部门号)
  • 上表和职称表相连(员工号)
  • 可以根据两个条件分组,且有优先顺序
select *
from dept_emp
left join departments on dept_emp.dept_no=departments.dept_no

10001|d001|1986-06-26|9999-01-01|d001|Marketing
10002|d001|1996-08-03|9999-01-01|d001|Marketing
10003|d002|1995-12-03|9999-01-01|d002|Finance

select dept_no,dept_name,title,count(title) count
from
(select dept_emp.dept_no,emp_no,dept_name
from dept_emp
left join departments on dept_emp.dept_no=departments.dept_no) as t

join titles on t.emp_no=titles.emp_no
group by dept_no,title
order by dept_no

28.查找描述信息中包含robot的电影对应的分类名称以及电影数目,而且还需要该分类对应电影数量>=5部

  • 满足条件的电影分类有哪些select film_id,category_id,count(film_id) category_num from film_category GROUP BY category_id having count(film_id)>=5
  • 描述中含有robot
  • 电影分类名称以及数目
select category.name,count(film.film_id)
from
(select film_id,category_id,count(film_id) category_num from film_category GROUP BY category_id having count(film_id)>=5) as t,
film,category,film_category
where film.description LIKE '%robot%'
and film.film_id=film_category.film_id and category.category_id=film_category.category_id # 三个表相连 and t.category_id=category.category_id # 满足条件的电影分类
原文地址:https://www.cnblogs.com/Cookie-Jing/p/14902281.html