牛客网SQL刷题笔记(MySQL)

牛客网SQL刷题笔记(MySQL)

此博客集合LeetCode、牛客网常见的题型及其解法,侵删

目录

类型1:查找排名第几的数据

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

题目:请你查找employees里入职员工时间排名倒数第三的员工所有信息。
注意:可能会存在同一个日期入职的员工,所以入职员工时间排名倒数第三的员工可能不止一个。
员工employees表简况如下:

emp_no birth_date first_name last_name gender hire_date
10001 1953-09-02 Georgi Facello M 1986-06-26
10002 1964-06-02 Bezalel Simmel F 1985-11-21
10003 1959-12-03 Parto Bamford M 1986-08-28
10004 1954-05-01 Christian Koblick M 1986-12-01
解法1:子查询+distinct。
select * from employees
where hire_date = (select distinct hire_date 
from employees 
order by hire_date desc limit 2,1)

解法2:子查询+group by,目前大部分情况最好用group by,因为group by比distinct快的多。

select * from employees 
where hire_date = (select hire_date 
from employees 
group by hire_date 
order by hire_date desc limit 2,1)
SQL12 获取每个部门中当前员工薪水最高的相关信息

题目:获取每个部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary,按照部门编号dept_no升序排列。

类似的题目:leetcode:查询每个部门工资最多的员工

员工表dept_emp简况如下:

emp_no dept_no from_date to_date
10001 d001 1986-06-26 9999-01-01
10002 d001 1996-08-03 9999-01-01
10003 d002 1990-08-05 9999-01-01

薪水表salaries简况如下:

emp_no salary from_date to_date
1001 88958 2002-06-22 9999-01-01
1002 72527 2001-08-22 9999-01-01
1003 43311 2001-12-01 9999-01-01

解法:因为每个部门可能有多个最大的salary,因此在第一层查询中不要包括员工的信息,先求出每个部门最大的salary及其对应的dept_no。

select dept_no,max(salary)
from dept_emp join salaries on dept_emp.emp_no=salaries.emp_no 
where salaries.to_date='9999-01-01' and dept_emp.to_date='9999-01-01' 
group by dept_no

再用查找到的记录来对应emp_no。

select dept_emp.dept_no,dept_emp.emp_no,salary as maxSalary
from dept_emp join salaries on dept_emp.emp_no=salaries.emp_no
where (dept_no,salary) in (select dept_no,max(salary)
from dept_emp join salaries on dept_emp.emp_no=salaries.emp_no 
where salaries.to_date='9999-01-01' and dept_emp.to_date='9999-01-01' 
group by dept_no)
ORDER by dept_no
SQL17 获取当前薪水第二多的员工的emp_no以及其对应的薪水salary

题目:请你获取薪水第二多的员工的emp_no以及其对应的薪水salary,
若有多个员工的薪水为第二多的薪水,则将对应的员工的emp_no和salary全部输出,并按emp_no升序排序。
薪水表salaries简况如下:

emp_no salary from_date to_date
1001 88958 2002-06-22 9999-01-01
1002 72527 2001-08-22 9999-01-01
1003 43311 2001-12-01 9999-01-01

解法1:子查询+distinct筛选出排名第几的值,然后返回去寻找emp_no。解法和此题一样:SQL2 查找入职员工时间排名倒数第三的员工所有信息

select emp_no, salary 
FROM salaries
where to_date = '9999-01-01' 
and salary = (select distinct salary 
from salaries 
order by salary desc
limit 1,1)

解法2:子查询+group by

select emp_no, salary 
FROM salaries
where to_date = '9999-01-01' 
and salary = (select salary 
from salaries 
group by salary
order BY salary desc
limit 1,1)
SQL18 获取当前薪水第二多的员工的emp_no以及其对应的薪水salary

请你查找薪水排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不能使用order by完成
员工表employees简况如下:

emp_no birth_date first_name last_name gender hire_date
10001 1953-09-02 Georgi Facello M 1986-06-26
10002 1964-06-02 Bezalel Simmel F 1985-11-21
10003 1959-12-03 Parto Bamford M 1986-08-28
10004 1954-05-01 Christian Koblick M 1986-12-01

薪水表salaries简况如下:

emp_no salary from_date to_date
1001 88958 2002-06-22 9999-01-01
1002 72527 2001-08-22 9999-01-01
1003 43311 2001-12-01 9999-01-01
1004 74057 2001-11-27 9999-01-01

解法:内连接+子查询+max嵌套,先查找表中最大的salary,再找小于这个salary的最大的值,如果题目改为查排名第三那就再嵌套一层。

select salaries.emp_no
,max(salary)
,employees.last_name
,employees.first_name
from employees join salaries 
on employees.emp_no=salaries.emp_no
where salary<(select max(salary) from salaries)
leecode176 第二高的薪水

题目:编写一个 SQL 查询,获取并返回 Employee 表中第二高的薪水 。如果不存在第二高的薪水,查询应该返回 null。
题目链接,点此进入

这里用判断空值的函数(ifnull)函数来处理特殊情况。
ifnull(a,b)函数解释:
如果value1不是空,结果返回a
如果value1是空,结果返回b

分析:因为此题结果只需要salary的值,所以不需要子查询,直接输出salary即可,另外,利用ifnull来判断是否存在第二高的薪水。
解法一:distinct

select ifNull((
select distinct Salary
from Employee
order by Salary desc limit 1,1),null) as SecondHighestSalary

解法一:group by

select ifNull((select salary
from employee
group by salary 
order by salary desc
limit 1,1),Null) as SecondHighestSalary
leecode177 第N高的薪水

题目:编写一个SQL查询来报告 Employee 表中第 n 高的工资。如果没有第 n 个最高工资,查询应该报告为 null。
题目链接,点此进入

解法:排名第N高意味着要跳过N-1个薪水,由于无法直接用limit N-1,所以需先在函数开头处理N为N=N-1。

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
  set N=N-1;
  RETURN (
      # Write your MySQL query statement below.
      select ifNull((select salary
      from employee 
      group by salary 
      order by salary desc 
      limit N,1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值