以下是牛客SQL的较难、困难所有题解
较难
获取当前薪水第二多的员工的emp_no以及其对应的薪水salary
获取当前薪水第二多的员工的emp_no以及其对应的薪水salary牛客题霸牛客网 (nowcoder.com)
题目分析:题解 | #获取当前薪水第二多的员工#_牛客网 (nowcoder.com)
SELECT s.emp_no,s.salary,
e.last_name,e.first_name
FROM salaries s
JOIN employees e USING(emp_no)
WHERE s.salary = (
SELECT max(salary)
FROM salaries
WHERE salary < (
SELECT max(salary)
FROM salaries
WHERE to_date = '9999-01-01'
)
and to_date = '9999-01-01'
) and s.to_date = '9999-01-01'
对所有员工的薪水按照salary降序进行1-N排名
对所有员工的薪水按照salary降序进行1-N的排名牛客题霸牛客网 (nowcoder.com)
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
SELECT emp_no,salary,
dense_rank () over (ORDER BY salary DESC) AS `rank`
FROM salaries
WHERE to_date = '9999-01-01' ;
获取所有非manager员工当前的薪水情况
获取所有非manager员工当前的薪水情况牛客题霸牛客网 (nowcoder.com)
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
SELECT dept_no,emp_no,salary
FROM dept_emp
JOIN salaries USING(emp_no)
WHERE emp_no NOT IN (
SELECT emp_no
FROM dept_manager
)
获取所有奖金的员工相关信息
获取有奖金的员工相关信息。牛客题霸牛客网 (nowcoder.com)
题解:题解 | #获取有奖金的员工相关信息。#_牛客网 (nowcoder.com)
SELECT emp_no,first_name,last_name,btype,salary,
ROUND(
CASE
WHEN btype = 1 THEN salary * 0.1
WHEN btype = 2 THEN salary * 0.2
ELSE salary * 0.3
END
,1) bonus
FROM employees
JOIN emp_bonus USING(emp_no)
JOIN salaries USING(emp_no)
WHERE to_date = '9999-01-01'
统计salary的累计和running_total
统计salary的累计和running_total牛客题霸牛客网 (nowcoder.com)
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
SELECT emp_no,
salary,
SUM(salary) OVER(ORDER BY emp_no) running_total
FROM salaries
WHERE to_date = '9999-01-01'
给出employees表中排名为奇数行的first_name
给出employees表中排名为奇数行的first_name牛客题霸牛客网 (nowcoder.com)
题解:题解 | #给出employees表中排名为奇数行#_牛客网 (nowcoder.com)
SELECT first_name
FROM employees JOIN(
SELECT first_name,
ROW_NUMBER() OVER(ORDER BY first_name) r_num
FROM employees
) t USING(first_name)
WHERE r_num % 2 = 1
异常的邮件
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
SELECT date,
ROUND(
AVG(IF(type='no_completed',1,0))
,3) p
FROM email
WHERE send_id IN (
SELECT id
FROM user
WHERE is_blacklist = 0
) AND receive_id IN (
SELECT id
FROM user
WHERE is_blacklist = 0
)
GROUP BY date
ORDER BY date
牛客每个人最近的登录日期(二)
牛客每个人最近的登录日期(二)牛客题霸牛客网 (nowcoder.com)
题解:题解 | #牛客每个人最近的登录日期(二)#_牛客网 (nowcoder.com)
SELECT u.name AS u_n,c.name AS c_n,
l.date
FROM
login l
JOIN user u ON l.user_id = u.id
JOIN client c ON l.client_id = c.id
WHERE (l.user_id, l.date) IN (
SELECT user_id,MAX(date)
FROM login
GROUP BY user_id
)
ORDER BY u_n;
牛客每个人最近的登录日期(三)
牛客每个人最近的登录日期(三)牛客题霸牛客网 (nowcoder.com)
题解:题解 | #牛客每个人最近的登录日期(三)#_牛客网 (nowcoder.com)
select round(count(distinct user_id)/(
select count(distinct user_id)
from login)
,3)
from login
where (user_id,date) in (
select user_id,DATE_ADD(min(date),INTERVAL 1 DAY)
from login
group by user_id);
牛客每个人最近的登录日期(四)
牛客每个人最近的登录日期(四)牛客题霸牛客网 (nowcoder.com)
题解:题解 | #牛客每个人最近的登录日期(四)#_牛客网 (nowcoder.com)
select date
,count(distinct
case
when (user_id,date) in
(select user_id,min(date)
from login
group by user_id) then user_id
else null
end)
from login
group by date
order by date;
牛客每个人最近的登录日期(六)
牛客每个人最近的登录日期(六)牛客题霸牛客网 (nowcoder.com)
题解:题解 | #牛客每个人最近的登录日期(六)#_牛客网 (nowcoder.com)
select u.name as u_n
,p.date as date
,sum(p.number)over(partition by u.name order by date)as ps_num
from passing_number p,user u
where p.user_id=u.id
order by p.date,u.name;
考试分数(三)
题解:题解 | #考试分数(三)#_牛客网 (nowcoder.com)
SELECT a.id,l.name,a.score
FROM
language AS l
JOIN (
SELECT id,language_id,score,
dense_rank() over (PARTITION BY language_id ORDER BY score DESC
) AS rank_num
FROM grade
) a ON l.id = a.language_id
WHERE rank_num <= 2
ORDER BY l.name,a.score DESC,a.id;
考试分数(四)
题解:题解 | #考试分数(四)#_牛客网 (nowcoder.com)
SELECT job,
FLOOR((COUNT(1) + 1) / 2) start,
FLOOR(COUNT(1) / 2 + 1) end
FROM grade
GROUP BY job
ORDER BY job
-- 3个数 start = 2,end = 2
-- 4个数 statr = 2,end = 3
-- start = (n + 1) / 2
-- end = n / 2 + 1
牛客的课程订单分析(四)
牛客的课程订单分析(四)牛客题霸牛客网 (nowcoder.com)
题解:题解 | #牛客的课程订单分析(四)#_牛客网 (nowcoder.com)
select user_id,min(date) first_buy_date,count(1) cnt
from order_info
where date > '2025-10-15'
and product_name in ('C++','Java','Python')
and status = 'completed'
group by user_id
having count(user_id) > 1
order by user_id
牛客的课程订单分析(七)
牛客的课程订单分析(七)牛客题霸牛客网 (nowcoder.com)
题解:题解 | #牛客的课程订单分析(七)#_牛客网 (nowcoder.com)
SELECT IF(a.client_id = 0,'GroupBuy',c.name) AS source,COUNT(*) AS cnt
FROM
(SELECT client_id
FROM order_info
WHERE date > '2025-10-15' AND status = 'completed' AND product_name IN ('C++','Java','Python')
AND user_id IN (SELECT user_id
FROM order_info
WHERE status = 'completed' AND status = 'completed' AND product_name IN ('C++','Java','Python')
GROUP BY user_id
HAVING COUNT(*) >= 2 ) ) a
LEFT JOIN client c ON a.client_id = c.id
GROUP BY a.client_id
ORDER BY source
最差是第几名(二)
最差是第几名(二)牛客题霸牛客网 (nowcoder.com)
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
select grade
from (select grade,(
SELECT sum(number)
FROM class_grade
) as total,
sum(number) over (order by grade) a,
sum(number) over (order by grade desc) b
from class_grade
) t1
where a >= total / 2 and b >= total / 2
order by grade;
获得积分最多的人
获得积分最多的人(二)牛客题霸牛客网 (nowcoder.com)
题解:题解 | #获得积分最多的人(二)#_牛客网 (nowcoder.com)
select user.id, user.name,t.grade_sum from(
select user_id,sum(grade_num) as grade_sum from grade_info group by user_id
having grade_sum=(select sum(grade_num) as grade_sum from grade_info group by user_id order by grade_sum desc limit 1)
) t
join user
on t.user_id=user.id
order by user.id
网易云音乐推荐(网易校招笔试真题)
网易云音乐推荐(网易校招笔试真题)牛客题霸牛客网 (nowcoder.com)
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
with t1 as (
SELECT DISTINCT music_name
FROM follow
JOIN music_likes
on follow.follower_id = music_likes.user_id
JOIN music
on music_likes.music_id = music.id
WHERE follow.user_id = 1 and music_name NOT IN(
SELECT music_name
FROM music_likes
JOIN music
ON music_likes.music_id = music.id
WHERE music_likes.user_id = 1
)
)
SELECT t1.music_name
FROM t1
JOIN music on t1.music_name = music.music_name
ORDER BY music.id
困难
获取每个部门当前员工薪水最高的相关信息
获取每个部门中当前员工薪水最高的相关信息牛客题霸牛客网 (nowcoder.com)
题解:题解 | #获取每个部门中当前员工薪水最高的相关信息#_牛客网 (nowcoder.com)
SELECT dept_no,emp_no,salary as maxSalary
FROM dept_emp
JOIN salaries USING(emp_no)
WHERE (dept_no,salary) in (
SELECT dept_no,max(salary)
FROM dept_emp
JOIN salaries USING(emp_no)
GROUP BY dept_no
)
ORDER BY dept_no
窗口函数做法:
SELECT t.dept_no,t.emp_no,t.salary AS maxSalary
FROM(SELECT d.dept_no,d.emp_no,s.salary,
DENSE_RANK() OVER (PARTITION BY d.dept_no ORDER BY s.salary DESC) AS sal_rank
FROM dept_emp d
JOIN salaries s ON d.emp_no = s.emp_no
) t
WHERE t.sal_rank = 1
ORDER BY t.dept_no;
查找职员入职以来的薪水涨幅情况
查找在职员工自入职以来的薪水涨幅情况牛客题霸牛客网 (nowcoder.com)
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
select b.emp_no,(b.salary-a.salary) as growth
from (select e.emp_no,s.salary
from employees e left join salaries s on e.emp_no=s.emp_no
WHERE e.hire_date=s.from_date)a -- 入职工资表
inner join
(select e.emp_no,s.salary
from employees e left join salaries s on e.emp_no=s.emp_no
where s.to_date='9999-01-01')b -- 现在工资表
on a.emp_no=b.emp_no
order by growth
获取员工当前薪水比其manger还高的相关信息
获取员工其当前的薪水比其manager当前薪水还高的相关信息牛客题霸牛客网 (nowcoder.com)
题解:题解 | #获取员工薪水比其manager薪水还高#_牛客网 (nowcoder.com)
SELECT t2.emp_no as emp_no,
t1.emp_no as manager_no,
t2.salary as emp_salary,
t1.salary as manager_salary
FROM (SELECT m.dept_no,m.emp_no,s.salary
FROM dept_manager m
JOIN salaries s USING(emp_no)
WHERE s.to_date = '9999-01-01'
) t1 -- 领导信息
JOIN (SELECT e.dept_no,e.emp_no,s.salary
FROM dept_emp e
JOIN salaries s USING(emp_no)
WHERE (dept_no,emp_no) NOT IN(
SELECT dept_no,emp_no
FROM dept_manager
) AND s.to_date = '9999-01-01'
) t2 -- 员工信息
on t1.dept_no = t2.dept_no
WHERE t1.salary < t2.salary
汇总各个部门当前员工的title类型的分配数目
汇总各个部门当前员工的title类型的分配数目牛客题霸牛客网 (nowcoder.com)
题解:题解 | #汇总各个部门当前员工的title类型的分配数目#_牛客网 (nowcoder.com)
SELECT dept_no,dept_name,title,count(1) 'count'
FROM dept_emp
JOIN titles USING(emp_no)
JOIN departments USING(dept_no)
WHERE dept_emp.to_date = '9999-01-01'
GROUP BY dept_no,title
ORDER BY dept_no,title
牛客每个人最近的登录日期
牛客每个人最近的登录日期(五)牛客题霸牛客网 (nowcoder.com)
题解:题解 | #牛客每个人最近的登录日期(五)#_牛客网 (nowcoder.com)
SELECT a.date,ROUND(
COUNT(DISTINCT login.user_id)/ COUNT(a.user_id)
,3) AS p
FROM (SELECT user_id,MIN(date) AS date
FROM login
GROUP BY user_id) AS a
LEFT JOIN login
ON login.user_id=a.user_id
AND login.date=DATE_ADD(a.date,INTERVAL 1 DAY)
GROUP BY a.date
UNION
SELECT date,0.000 AS p
FROM login
WHERE date NOT IN(
SELECT MIN(date)
FROM login
GROUP BY user_id)
ORDER BY date;
考试分数(五)
题解:题解 | #考试分数(五)#_牛客网 (nowcoder.com)
SELECT id,job,score,rk_b as t_rank
FROM (SELECT id,job,score,
ROW_NUMBER()OVER(PARTITION BY job ORDER BY score) rk_a,
ROW_NUMBER()OVER(PARTITION BY job ORDER BY score DESC) rk_b
FROM grade
) m
JOIN (
SELECT job,count(1) job_count
FROM grade
GROUP BY job
) n
USING (job)
WHERE rk_a >= job_count / 2 AND rk_b >= job_count / 2
ORDER BY id
牛客的课程订单分析(五)
牛客的课程订单分析(五)牛客题霸牛客网 (nowcoder.com)
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
SELECT DISTINCT t3.user_id,t1.first_buy_date,t2.second_buy_date,t3.cnt
FROM(SELECT user_id,date as first_buy_date
FROM(SELECT user_id,date,
ROW_NUMBER()OVER(PARTITION BY user_id ORDER BY date) rk
FROM order_info
WHERE date > '2025-10-15'
and product_name in ('C++','Java','Python')
and status = 'completed'
) t
WHERE rk = 1
) t1
JOIN (
SELECT user_id,date as second_buy_date
FROM(SELECT user_id,date,
ROW_NUMBER()OVER(PARTITION BY user_id ORDER BY date) rk
FROM order_info
WHERE date > '2025-10-15'
and product_name in ('C++','Java','Python')
and status = 'completed'
) t
WHERE rk = 2
) t2 on t1.user_id = t2.user_id
JOIN (
SELECT user_id,count(1) cnt
FROM order_info
WHERE date > '2025-10-15'
and product_name in ('C++','Java','Python')
and status = 'completed'
GROUP BY user_id
HAVING count(1) > 1
) t3 ON t1.user_id = t3.user_id
ORDER BY t3.user_id
--开窗函数解法
select
a.*
from
(select
user_id,
min(date) over(partition by user_id) as first_buy_date,
lead(date,1,0) over(partition by user_id order by date) as second_buy_date,
count(*) over(partition by user_id) as cnt
from order_info
where date>='2025-10-16'
and status='completed'
and product_name in('C++','Java','Python')
) a
where a.cnt>=2
group by a.user_id
order by a.user_id ;
实习广场投递简历
实习广场投递简历分析(三)牛客题霸牛客网 (nowcoder.com)
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
SELECT m.job,m.first_year_mon,m.first_year_cnt,
n.second_year_mon,n.second_year_cnt
FROM (SELECT job,date_format(date,'%Y-%m') first_year_mon,sum(num) first_year_cnt
FROM resume_info
WHERE year(date) = 2025
GROUP BY job,first_year_mon
) m
JOIN (SELECT job,date_format(date,'%Y-%m') second_year_mon,sum(num) second_year_cnt
FROM resume_info
WHERE year(date) = 2026
GROUP BY job,second_year_mon -- 将 first_year_mon 改为 second_year_mon
) n on m.job = n.job
WHERE left(m.first_year_mon,4) = left(n.second_year_mon,4) - 1 -- 年份差1
AND substr(m.first_year_mon,6,2) = substr(n.second_year_mon,6,2) -- 月份相同
ORDER BY m.first_year_mon DESC,m.job DESC
-- 困惑 把年份、月份判定改成下面这个,牛客输出是对的,但报答案错误
WHERE YEAR(DATE_SUB(n.second_year_mon, INTERVAL 1 YEAR)) = YEAR(m.first_year_mon)
AND MONTH(n.second_year_mon) = MONTH(m.first_year_mon)
ORDER BY m.first_year_mon DESC,m.job DESC
获取积分最多的人(三)
获得积分最多的人(三)牛客题霸牛客网 (nowcoder.com)
题解:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
with t1 as(
SELECT user_id,
sum(
case WHEN type = 'add' then grade_info.grade_num
else -grade_info.grade_num end
) grade_num
FROM grade_info
GROUP BY user_id
)-- 得到user_id、总的grade_num积分
SELECT t1.user_id,user.name,t1.grade_num
FROM t1
JOIN user on t1.user_id = user.id
WHERE t1.grade_num = (
SELECT max(grade_num)
FROM t1
)
ORDER BY t1.user_id