【SQL】 牛客网SQL训练Part1 简单难度

 

 

地址位置:

https://www.nowcoder.com/exam/oj?difficulty=2

  

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

-- 准备脚本
drop table if exists  `employees` ; 
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`));
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');
INSERT INTO employees VALUES(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12');
INSERT INTO employees VALUES(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02');
INSERT INTO employees VALUES(10007,'1957-05-23','Tzvetan','Zielinski','F','1989-02-10');
INSERT INTO employees VALUES(10008,'1958-02-19','Saniya','Kalloufi','M','1994-09-15');
INSERT INTO employees VALUES(10009,'1952-04-19','Sumant','Peac','F','1985-02-18');
INSERT INTO employees VALUES(10010,'1963-06-01','Duangkaew','Piveteau','F','1989-08-24');
INSERT INTO employees VALUES(10011,'1953-11-07','Mary','Sluis','F','1990-01-22');

-- 按默认的情况筛选
SELECT * FROM `employees` ORDER BY hire_date DESC LIMIT 2, 1

-- 如果时间存在多个同样的,去重处理后再查询
SELECT *
FROM employees
WHERE hire_date = (
    SELECT DISTINCT hire_date
    FROM employees
    ORDER BY hire_date DESC       -- 倒序
    LIMIT 1 OFFSET 2              -- 去掉排名倒数第一第二的时间,取倒数第三
);

 

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

drop table if exists  `dept_emp` ; 
drop table if exists  `employees` ; 
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`));
INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01');
INSERT INTO dept_emp VALUES(10002,'d002','1996-08-03','9999-01-01');
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');

-- 查询SQL
SELECT 
    A.last_name,
    A.first_name,
    B.dept_no
FROM
    employees AS A
    LEFT JOIN dept_emp AS B ON A.emp_no = B.emp_no 
WHERE B.DEPT_NO IS NOT NULL

  

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

drop table if exists  `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`));
INSERT INTO salaries VALUES(10001,60117,'1986-06-26','1987-06-26');
INSERT INTO salaries VALUES(10001,62102,'1987-06-26','1988-06-25');
INSERT INTO salaries VALUES(10001,66074,'1988-06-25','1989-06-25');
INSERT INTO salaries VALUES(10001,66596,'1989-06-25','1990-06-25');
INSERT INTO salaries VALUES(10001,66961,'1990-06-25','1991-06-25');
INSERT INTO salaries VALUES(10001,71046,'1991-06-25','1992-06-24');
INSERT INTO salaries VALUES(10001,74333,'1992-06-24','1993-06-24');
INSERT INTO salaries VALUES(10001,75286,'1993-06-24','1994-06-24');
INSERT INTO salaries VALUES(10001,75994,'1994-06-24','1995-06-24');
INSERT INTO salaries VALUES(10001,76884,'1995-06-24','1996-06-23');
INSERT INTO salaries VALUES(10001,80013,'1996-06-23','1997-06-23');
INSERT INTO salaries VALUES(10001,81025,'1997-06-23','1998-06-23');
INSERT INTO salaries VALUES(10001,81097,'1998-06-23','1999-06-23');
INSERT INTO salaries VALUES(10001,84917,'1999-06-23','2000-06-22');
INSERT INTO salaries VALUES(10001,85112,'2000-06-22','2001-06-22');
INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1996-08-03','1997-08-03');

-- GROUP BY  + HAVING 筛选
SELECT `emp_no`, COUNT(`emp_no`) AS `t`
FROM `salaries`
GROUP BY `emp_no`
HAVING `t` > 15

  

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

drop table if exists  `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`));
INSERT INTO salaries VALUES(10001,72527,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01');

-- 对这个薪资进行去重即可
SELECT DISTINCT `salary` FROM `salaries` ORDER BY `salary` DESC 

  

获取所有非manager的员工emp_no

drop table if exists  `dept_manager` ; 
drop table if exists  `employees` ; 
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) 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`));
INSERT INTO dept_manager VALUES('d001',10002,'1996-08-03','9999-01-01');
INSERT INTO dept_manager VALUES('d002',10003,'1990-08-05','9999-01-01');
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');

-- 按员工表作为主表,联表,筛选条件为 部门号为空的记录
SELECT
	A.emp_no
FROM 
	`employees` AS A
	LEFT JOIN `dept_manager` AS B ON A.emp_no = B.emp_no
WHERE B.dept_no IS NULL

  

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

请你查找

1、employees表所有emp_no为奇数,

2、且last_name不为Mary的员工信息,

3、并按照hire_date逆序排列,

drop table if exists  `employees` ; 
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`));
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Bezalel','Mary','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');
INSERT INTO employees VALUES(10005,'1953-11-07','Mary','Sluis','F','1990-01-22');

-- 按条件写SQL查询
SELECT *
FROM employees 
WHERE `emp_no` MOD 2 != 0 AND `last_name` != 'Mary'
ORDER BY `hire_date` DESC

  

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

drop table if exists  `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`));
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01');

-- 按薪资倒序
SELECT `emp_no`, `salary` 
FROM `salaries` 
ORDER BY `salary` DESC LIMIT 1, 1

 

将employees表的所有员工的last_name和first_name拼接起来作为Name

drop table if exists  `employees` ; 
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`));
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');
INSERT INTO employees VALUES(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12');
INSERT INTO employees VALUES(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02');
INSERT INTO employees VALUES(10007,'1957-05-23','Tzvetan','Zielinski','F','1989-02-10');
INSERT INTO employees VALUES(10008,'1958-02-19','Saniya','Kalloufi','M','1994-09-15');
INSERT INTO employees VALUES(10009,'1952-04-19','Sumant','Peac','F','1985-02-18');
INSERT INTO employees VALUES(10010,'1963-06-01','Duangkaew','Piveteau','F','1989-08-24');
INSERT INTO employees VALUES(10011,'1953-11-07','Mary','Sluis','F','1990-01-22');

-- CONCAT 合并函数
SELECT CONCAT(`last_name`, ' ', `first_name`) AS `Name` 
FROM `employees`

  

批量插入数据

DROP TABLE if exists actor;
CREATE TABLE actor (
	actor_id  smallint(5)  NOT NULL PRIMARY KEY,
	first_name  varchar(45) NOT NULL,
	last_name  varchar(45) NOT NULL,
	last_update  DATETIME NOT NULL
);

-- 插入SQL
INSERT INTO `actor`VALUES 
(1, 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'),
(2, 'NICK', 'WAHLBERG', '2006-02-15 12:34:33');

  

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

DROP TABLE if exists titles_test;
CREATE TABLE titles_test (
   id int(11) not null primary key,
   emp_no  int(11) NOT NULL,
   title  varchar(50) NOT NULL,
   from_date  date NOT NULL,
   to_date  date DEFAULT NULL);

insert into titles_test values
('1', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('2', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('3', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('4', '10004', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('5', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('6', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('7', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01');

-- 1、按员工编号分组Group筛选唯一记录,并按照最小主键值筛选,
-- 2、删除时进行取反获取重复记录
-- 3、删除表时查询不能再声明是这张表,需要设置别名
DELETE FROM `titles_test`
WHERE `id` NOT IN(
	SELECT * FROM (
		SELECT MIN(`id`) FROM `titles_test` GROUP BY emp_no 
	) AS `tt`
); 

  

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

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

2、且 from_date更新为2001-01-01。

DROP TABLE IF EXISTS titles_test;
CREATE TABLE  titles_test (
   id int(11) not null primary key,
   emp_no  int(11) NOT NULL,
   title  varchar(50) NOT NULL,
   from_date  date NOT NULL,
   to_date  date DEFAULT NULL);

insert into  values
('1', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('2', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('3', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('4', '10004', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('5', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('6', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('7', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01');

-- 更新记录
UPDATE `titles_test` 
SET `to_date` = NULL, `from_date` = '2001-01-01'
WHERE `to_date` = '9999-01-01'

 

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

其他数据保持不变,使用replace实现,直接使用update会报错。
drop table if exists titles_test;
CREATE TABLE titles_test (
   id int(11) not null primary key,
   emp_no  int(11) NOT NULL,
   title  varchar(50) NOT NULL,
   from_date  date NOT NULL,
   to_date  date DEFAULT NULL);

insert into titles_test values
('1', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('2', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('3', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('4', '10004', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('5', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('6', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('7', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01');


-- 1、主键重复警告风险 Duplicate entry '5' for key 'titles_test.PRIMARY'
UPDATE `titles_test`
SET `id` = 5, `emp_no` = 10005
WHERE `id` = 5 AND `emp_no` = 10001

-- 2、使用Replace函数更新?
UPDATE `titles_test`
SET `emp_no` = REPLACE(`emp_no`, 10001, 10005)
WHERE `id` = 5;

-- 3、ON DUPLICATE KEY UPDATE 主键冲突触发更新
INSERT INTO titles_test
VALUES(5, 10001 ,'Senior Engineer', '1986-06-26', '9999-01-01')
ON DUPLICATE KEY UPDATE emp_no = 10005;

-- 4、遇到主键冲突时,优先进行UPDATE操作
REPLACE INTO titles_test VALUES(5, 10005 ,'Senior Engineer', '1986-06-26', '9999-01-01') ;

 

将titles_test表名修改为titles_2017 

drop table if exists titles_test;
drop table if exists titles_2017;
CREATE TABLE titles_test (
   id int(11) not null primary key,
   emp_no  int(11) NOT NULL,
   title  varchar(50) NOT NULL,
   from_date  date NOT NULL,
   to_date  date DEFAULT NULL);

insert into  values
('1', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('2', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('3', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('4', '10004', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('5', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('6', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('7', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01');

-- ALTER TABLE 语法
ALTER TABLE `titles_test` RENAME TO `titles_2017`;

  

出现三次以上相同积分的情况

drop table if exists grade;
CREATE TABLE `grade` (
`id` int(4) NOT NULL,
`number` int(4) NOT NULL,
PRIMARY KEY (`id`));

INSERT INTO grade VALUES
(1,111),
(2,333),
(3,111),
(4,111),
(5,333);

-- 分组后筛选即可
SELECT `number`
FROM `grade` 
GROUP BY `number`
HAVING COUNT(`number`) > 2

  

找到每个人的任务

drop table if exists person;
drop table if exists task;
CREATE TABLE `person` (
`id` int(4) NOT NULL,
`name` varchar(32) NOT NULL,
PRIMARY KEY (`id`));

CREATE TABLE `task` (
`id` int(4) NOT NULL,
`person_id` int(4) NOT NULL,
`content` varchar(32) NOT NULL,
PRIMARY KEY (`id`));

INSERT INTO person VALUES
(1,'fh'),
(2,'tm');

INSERT INTO task VALUES
(1,2,'tm works well'),
(2,2,'tm works well');

SELECT
	`p`.`id`,
	`p`.`name`,
	`t`.`content`
FROM 
	`person` AS `p`
	LEFT JOIN `task` AS `t` ON `t`.person_id = `p`.`id`

 

每个人最近的登录日期

drop table if exists login;
drop table if exists user;
drop table if exists client;
CREATE TABLE login (
id int(4) NOT NULL,
user_id int(4) NOT NULL,
client_id int(4) NOT NULL,
date date NOT NULL,
PRIMARY KEY (id));

CREATE TABLE user (
id int(4) NOT NULL,
name varchar(32) NOT NULL,
PRIMARY KEY (id));

CREATE TABLE client (
id int(4) NOT NULL,
name varchar(32) NOT NULL,
PRIMARY KEY (id));

INSERT INTO login VALUES
(1,2,1,'2020-10-12'),
(2,3,2,'2020-10-12'),
(3,2,2,'2020-10-13'),
(4,3,2,'2020-10-13');

INSERT INTO user VALUES
(1,'tm'),
(2,'fh'),
(3,'wangchao');

INSERT INTO client VALUES
(1,'pc'),
(2,'ios'),
(3,'anroid'),
(4,'h5');

SELECT * FROM login

-- 按用户ID进行分组,取日期最大值(即最近一次登录时间)
select user_id,MAX(date) as recent_login_date
from login group by user_id order by user_id;

  

考试分数

第1行表示用户id为1的用户选择了C++岗位并且考了11001分

。。。

第8行表示用户id为8的用户选择了JS岗位并且考了9999分

请你写一个sql语句查询各个岗位分数的平均数,并且按照分数降序排序,

结果保留小数点后面3位(3位之后四舍五入):

drop table if exists grade;
CREATE TABLE  grade(
`id` int(4) NOT NULL,
`job` varchar(32) NOT NULL,
`score` int(10) NOT NULL,
PRIMARY KEY (`id`));

INSERT INTO grade VALUES
(1,'C++',11001),
(2,'C++',10000),
(3,'C++',9000),
(4,'Java',12000),
(5,'Java',13000),
(6,'JS',12000),
(7,'JS',11000),
(8,'JS',9999);

-- 对job进行分组,然后取成绩平均值,并设置四舍五入
SELECT `job`, ROUND(AVG(`score`), 3) AS `AVG_SCORE`
FROM `grade`
GROUP BY `job`
ORDER BY `AVG_SCORE` DESC

  

课程订单分析:

请你写出一个sql语句查询

1、在2025-10-15以后

2、状态为购买成功的C++课程或者Java课程或者Python的订单,

3、并且按照order_info的id升序排序

drop table if exists order_info;
CREATE TABLE order_info (
id int(4) NOT NULL,
user_id int(11) NOT NULL,
product_name varchar(256) NOT NULL,
status varchar(32) NOT NULL,
client_id int(4) NOT NULL,
date date NOT NULL,
PRIMARY KEY (id));

INSERT INTO order_info VALUES
(1,557336,'C++','no_completed',1,'2025-10-10'),
(2,230173543,'Python','completed',2,'2025-10-12'),
(3,57,'JS','completed',3,'2025-10-23'),
(4,57,'C++','completed',3,'2025-10-23'),
(5,557336,'Java','completed',1,'2025-10-23'),
(6,557336,'Python','no_completed',1,'2025-10-24');

-- 按描述条件查询即可
SELECT *
FROM `order_info`
WHERE 
	`date` > '2025-10-15'
	AND `product_name` IN ('C++', 'Java', 'Python')
	AND `status` = 'completed'
ORDER BY `id` ASC

  

简历分析:

写出SQL语句查询在2025年内投递简历的岗位和数量,并且按数量降序排序

drop table if exists resume_info;
CREATE TABLE resume_info (
id int(4) NOT NULL,
job varchar(64) NOT NULL,
date date NOT NULL,
num int(11) NOT NULL,
PRIMARY KEY (id));

INSERT INTO resume_info VALUES
(1,'C++','2025-01-02',53),
(2,'Python','2025-01-02',23),
(3,'Java','2025-01-02',12),
(4,'Java','2025-02-03',24),
(5,'C++','2025-02-03',23),
(6,'Python','2025-02-03',34),
(7,'Python','2025-03-04',54),
(8,'C++','2025-03-04',65),
(9,'Java','2025-03-04',92),
(10,'Java','2026-01-04',230);


-- 1、使用YEAR函数筛选25年内的数据
-- 2、再对job分组,求和NUM字段
SELECT `job`, SUM(`NUM`) AS `cnt`
FROM `resume_info`
WHERE YEAR(`date`) = 2025
GROUP BY `job`
ORDER BY `cnt` DESC

  

 

posted @ 2022-05-27 17:18  emdzz  阅读(24)  评论(0编辑  收藏  举报