1. 程式人生 > 其它 >【SQL】 牛客網SQL訓練Part1 簡單難度

【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