SQL 牛客网刷题01——简单

目录

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

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

 3、查找所有已经分配部门的员工的last_name、first_name以及dept_no

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

 5、找出所有员工当前薪水salary情况、相同的薪水只显示一次,并按照逆序显示

6、获取所有非manager的员工emp_no,

7、查找employees表emp_no与last_name的员工信息

8、获取薪水第二多的员工的emp_no以及其对应的薪水salary,若有多个员工的薪水为第二多的薪水,全部输出并按emp_no升序排序。

9、所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分

10、对于表actor批量插入数据(不能有2条insert语句)

11、删除emp_no重复的记录,只保留最小的id对应的记录

12、将所有to_date为9999-01-01的全部更新为NULL

13、将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005

14、将titles_test表名修改为titles_2017

15、查询积分表里面出现三次以及三次以上的积分

 16、找到每个人的任务

 17、牛客每个人最近的登录日期(一)

18、查询各个岗位平均数,并按分数降序,保留小数点后面3位

19、牛客的课程订单分析(一)

20、实习广场投递简历分析(一)


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

SQL 牛客网刷题01——简单_第1张图片

# 方法一 :limit存在争议,可能有多位入职最晚的员工
select * from employees
order by hire_date desc
limit 1;

# 方法三:使用limit 与 offset关键字  
select * from employees
order by hire_date desc
limit 1 offset 0;
 
# 方法四:使用limit关键字 从第0条记录 向后读取一个,也就是第一条记录 
select * from employees
order by hire_date desc
limit 0,1;

# 方法五:使用子查询
select * from employees
where hire_date = (select max(hire_date) from employees);

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

SQL 牛客网刷题01——简单_第2张图片

# 方法一:子查询
# limit和offset组合,limit后面只能有一个参数,表示要取的的数量,offset表示要跳过的数量
select * from employees
where hire_date = (
    select distinct hire_date from employees e
    order by hire_date desc
    limit 1 offset 2);

# 方法二:dense_rank() 窗口函数
select emp_no,birth_date,first_name,last_name,gender,hire_date
from(
select *,
dense_rank() over(order by hire_date desc )as n
from employees
) a
where n=3;

 3、查找所有已经分配部门的员工的last_name、first_name以及dept_no

SQL 牛客网刷题01——简单_第3张图片

# where条件
SELECT e.last_name, e.first_name, d.dept_no
FROM employees AS e, dept_emp AS d
WHERE e.emp_no = d.emp_no;

# 左联结
SELECT e.last_name, e.first_name, d.dept_no
FROM employees AS e INNER JOIN dept_emp AS d
ON e.emp_no=d.emp_no;

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

SQL 牛客网刷题01——简单_第4张图片

SELECT emp_no, COUNT(emp_no) AS t
FROM salaries
GROUP BY emp_no
HAVING t > 15;  -- 组筛选条件

 5、找出所有员工当前薪水salary情况、相同的薪水只显示一次,并按照逆序显示

# 方法一:distinct+order by
SELECT DISTINCT salary
FROM salaries
WHERE to_date='9999-01-01'
ORDER BY salary DESC;

# 方法二:group by
SELECT salary
FROM salaries
WHERE to_date='9999-01-01'
GROUP BY salary
ORDER BY salary DESC

6、获取所有非manager的员工emp_no,

# 方法1:NOT IN+子查询
select emp_no
from employees
where emp_no not in (select emp_no from dept_manager);

# 方法2:LEFT JOIN左连接+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;

7、查找employees表emp_no与last_name的员工信息

查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列

# 方法一: %
select * from employees
where emp_no % 2 =1
and last_name! = 'Mary'
order by hire_date desc;

# 方法二:&
SELECT * FROM employees
WHERE emp_no & 1
AND last_name<>'Mary'
ORDER BY hire_date DESC;

8、获取薪水第二多的员工的emp_no以及其对应的薪水salary,若有多个员工的薪水为第二多的薪水,全部输出并按emp_no升序排序。

# 方法一:子查询+DISTINCT
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 offset 1);

# 方法二:rank开窗函数(当薪水第二的人有多个时会全部输出)
select emp_no,salary from
(select emp_no,salary,rank() over(order by salary desc) t
from salaries
where to_date='9999-01-01')
where t=2;

9、所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分

# concat()可以按顺序连接,分隔符空格作为一个string放在两个字段中间
select concat(last_name, " ", first_name) from employees

10、对于表actor批量插入数据(不能有2条insert语句)

INSERT INTO actor(actor_id,
                  first_name,
                  last_name,
                  last_update)
VALUES(1,'PENELOPE','GUINESS','2006-02-15 12:34:33'),
      (2,'NICK','WAHLBERG','2006-02-15 12:34:33');

11、删除emp_no重复的记录,只保留最小的id对应的记录

# MySQL中不允许在子查询的同时删除表数据
DELETE FROM titles_test
WHERE id NOT IN(
    SELECT * FROM(
    SELECT MIN(id)
    FROM titles_test
    GROUP BY emp_no)a);  -- 把得出的表重命名那就不是原表了(机智.jpg

12、将所有to_date为9999-01-01的全部更新为NULL

update titles_test
set to_date = NULL, from_date = '2001-01-01'
where to_date = '9999-01-01';

13、将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005

# 方法一:REPLACE(X, Y, Z) 函数,X是要被处理的字符串,Y是X中将要被替换的字符串,Z是用来替换Y的字符串,最终返回替换后的字符串
UPDATE titles_test
SET emp_no = REPLACE(emp_no, 10001, 10005)
WHERE id = 5;

# 方法二:全字段替换,replace 是功能是:表内有相同数据则替换,没有则添加
REPLACE INTO titles_test
VALUES(5, 10005, 'Senior Engineer', '1986-06-26', '9999-01-01');

14、将titles_test表名修改为titles_2017

ALTER TABLE 表名 ADD 列名/索引/主键/外键等;
ALTER TABLE 表名 DROP 列名/索引/主键/外键等;
ALTER TABLE 表名 ALTER 仅用来改变某列的默认值;
ALTER TABLE 表名 RENAME 列名/索引名 TO 新的列名/新索引名;
ALTER TABLE 表名 RENAME TO/AS 新表名;
ALTER TABLE 表名 MODIFY 列的定义但不改变列名;
ALTER TABLE 表名 CHANGE 列名和定义都可以改变。

alter table titles_test rename  to titles_2017;

15、查询积分表里面出现三次以及三次以上的积分

SQL 牛客网刷题01——简单_第5张图片

# 方法一:having
select number from grade
group by number
having count(number) >= 3;

# 方法二:子查询
SELECT T.number from(
SELECT count(number) coun,number
from grade
group by number)as T
where T.coun>=3;

 16、找到每个人的任务

SQL 牛客网刷题01——简单_第6张图片

select p.id, p.name, t.content from person p
left join task as t on p.id =t.person_id
order by p.id;

 17、牛客每个人最近的登录日期(一)

# 方法一:max
select user_id, max(date) from login
group by user_id
order by user_id;

# 方法二:窗口函数
select user_id, `date`
from (
        select user_id, `date`,
        rank() over(partition by user_id order by date desc) rk
        from login
    ) t1
where rk = 1
order by  user_id;

18、查询各个岗位平均数,并按分数降序,保留小数点后面3位

select job,round(avg(score),3) as avg from grade 
group by job
order by avg desc; 

19、牛客的课程订单分析(一)

查询在2025-10-15以后状态为购买成功的C++课程或者Java课程或者Python的订单,并且按照order_info的id升序

select * from order_info
where date > '2025-10-15'
and status = 'completed'
and product_name in ('C++', 'Java','Python')
order by id;

20、实习广场投递简历分析(一)

在2025年内投递简历的岗位和数量,并且按数量降序排序

# 方法一:
select job, sum(num) cnt from resume_info
where date between '2025-0101' and '2025-12-31'
group by job
order by cnt desc;

# 方法二:date函数
SELECT job,
  sum(num) AS cnt
FROM resume_info
WHERE date_format(date,'%Y') = '2025'
GROUP BY job
ORDER BY cnt desc;

你可能感兴趣的