【SQL】 牛客網SQL訓練Part2 中等難度
查詢當前薪水詳情以及部門編號dept_no
查詢
1、各個部門當前領導的薪水詳情以及其對應部門編號dept_no,
2、輸出結果以salaries.emp_no升序排序,
3、並且請注意輸出結果裡面dept_no列是最後一列
drop table if exists `salaries` ; drop table if exists `dept_manager` ; 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`)); CREATE TABLE `dept_manager` ( `dept_no` char(4) NOT NULL, `emp_no` int(11) NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`dept_no`)); INSERT INTO dept_manager VALUES('d001',10002,'9999-01-01'); INSERT INTO dept_manager VALUES('d002',10006,'9999-01-01'); INSERT INTO dept_manager VALUES('d003',10005,'9999-01-01'); INSERT INTO dept_manager VALUES('d004',10004,'9999-01-01'); 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'); INSERT INTO salaries VALUES(10004,74057,'2001-11-27','9999-01-01'); INSERT INTO salaries VALUES(10005,94692,'2001-09-09','9999-01-01'); INSERT INTO salaries VALUES(10006,43311,'2001-08-02','9999-01-01'); INSERT INTO salaries VALUES(10007,88070,'2002-02-07','9999-01-01'); -- 按員工號聯表查詢 SELECT s.*, d.`dept_no` FROM `salaries` AS s LEFT JOIN `dept_manager` AS d ON s.`emp_no` = d.`emp_no` WHERE d.`dept_no` IS NOT NULL -- 必須要有部門才可以 AND d.TO_DATE = '9999-01-01' -- 日期必須是當前時間 ORDER BY d.`dept_no` ASC
查詢所有員工的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'); -- 左查詢完成 SELECT e.`last_name`, e.`first_name`, e_no.`dept_no` FROM `employees` AS e LEFT JOIN `dept_emp` AS e_no ON e.`emp_no` = e_no.`emp_no`
獲取所有員工當前的manager
獲取所有的員工和員工對應的經理,如果員工本身是經理的話則不顯示
drop table if exists `dept_emp` ; drop table if exists `dept_manager` ; 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 `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`)); INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01'); INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01'); INSERT INTO dept_emp VALUES(10003,'d002','1995-12-03','9999-01-01'); 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'); -- 1、先用部門進行關聯,2、再對員工則進行不等關聯,3、取指定時間 SELECT emp.emp_no, mgr.emp_no AS manager FROM `dept_emp` AS emp JOIN `dept_manager` AS mgr ON emp.dept_no = mgr.dept_no AND emp.emp_no != mgr.emp_no WHERE mgr.to_date = '9999-01-01' AND emp.to_date = '9999-01-01'
統計出當前各個title型別對應的員工當前薪水對應的平均工資
統計出各個title型別對應的員工薪水對應的平均工資avg。
結果給出title以及平均工資avg,並且以avg升序排序
drop table if exists `salaries` ; drop table if exists titles; 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`)); CREATE TABLE titles ( `emp_no` int(11) NOT NULL, `title` varchar(50) NOT NULL, `from_date` date NOT NULL, `to_date` date DEFAULT NULL); INSERT INTO salaries VALUES(10001,88958,'1986-06-26','9999-01-01'); INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01'); INSERT INTO salaries VALUES(10004,74057,'1995-12-01','9999-01-01'); INSERT INTO salaries VALUES(10006,43311,'2001-08-02','9999-01-01'); INSERT INTO salaries VALUES(10007,88070,'2002-02-07','9999-01-01'); INSERT INTO titles VALUES(10001,'Senior Engineer','1986-06-26','9999-01-01'); INSERT INTO titles VALUES(10003,'Senior Engineer','2001-12-01','9999-01-01'); INSERT INTO titles VALUES(10004,'Senior Engineer','1995-12-01','9999-01-01'); INSERT INTO titles VALUES(10006,'Senior Engineer','2001-08-02','9999-01-01'); INSERT INTO titles VALUES(10007,'Senior Staff','1996-02-11','9999-01-01'); -- 聯表,然後分組處理,計算AVG薪資 SELECT t.title,AVG(s.salary) AS `avg_salary` FROM `salaries` AS s LEFT JOIN `titles` AS t ON s.emp_no = t.emp_no GROUP BY t.title ORDER BY `avg_salary` ASC
查詢所有員工的last_name和first_name以及對應的dept_name
查詢所有員工的last_name和first_name以及對應的dept_name,也包括暫時沒有分配部門的員工
drop table if exists `departments` ; drop table if exists `dept_emp` ; drop table if exists `employees` ; CREATE TABLE `departments` ( `dept_no` char(4) NOT NULL, `dept_name` varchar(40) NOT NULL, PRIMARY KEY (`dept_no`)); 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 departments VALUES('d001','Marketing'); INSERT INTO departments VALUES('d002','Finance'); INSERT INTO departments VALUES('d003','Human Resources'); INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01'); INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01'); INSERT INTO dept_emp VALUES(10003,'d002','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'); INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01'); -- 全部左連,因為查詢所有員工,所以員工表是主表 SELECT E.last_name, E.first_name, D.dept_name FROM employees AS E LEFT JOIN dept_emp AS DE ON E.emp_no = DE.emp_no LEFT JOIN departments AS D ON D.dept_no = DE.dept_no
統計各個部門的工資記錄數
給出部門編碼dept_no、部門名稱dept_name以及部門在salaries表裡面有多少條記錄sum,
按照dept_no升序排序
drop table if exists `departments` ; drop table if exists `dept_emp` ; drop table if exists `salaries` ; CREATE TABLE `departments` ( `dept_no` char(4) NOT NULL, `dept_name` varchar(40) NOT NULL, PRIMARY KEY (`dept_no`)); 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 `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 departments VALUES('d001','Marketing'); INSERT INTO departments VALUES('d002','Finance'); INSERT INTO dept_emp VALUES(10001,'d001','2001-06-22','9999-01-01'); INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01'); INSERT INTO dept_emp VALUES(10003,'d002','1996-08-03','9999-01-01'); 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','9999-01-01'); INSERT INTO salaries VALUES(10003,32323,'1996-08-03','9999-01-01'); -- 1、各個部門,即按主表先查詢,然後是中間表和薪資表 -- 2、不能對不查詢的欄位進行分組,所以GroupBy只能對部門號和部門名分組 -- 3、分組後對其他欄位進行COUNT計數即可 SELECT D.dept_no, D.dept_name, COUNT(S.salary) AS sum FROM `departments` AS D LEFT JOIN dept_emp AS DE ON D.dept_no = DE.dept_no LEFT JOIN salaries AS S ON DE.emp_no = S.emp_no GROUP BY D.dept_no ORDER BY D.dept_no ASC
使用join查詢方式找出沒有分類的電影id以及名稱
drop table if exists film ; drop table if exists category ; drop table if exists film_category ; CREATE TABLE IF NOT EXISTS film ( film_id smallint(5) NOT NULL DEFAULT '0', title varchar(255) NOT NULL, description text, PRIMARY KEY (film_id)); CREATE TABLE category ( category_id tinyint(3) NOT NULL , name varchar(25) NOT NULL, `last_update` timestamp, PRIMARY KEY ( category_id )); CREATE TABLE film_category ( film_id smallint(5) NOT NULL, category_id tinyint(3) NOT NULL, `last_update` timestamp); INSERT INTO film VALUES(1,'ACADEMY DINOSAUR','A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies'); INSERT INTO film VALUES(2,'ACE GOLDFINGER','A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China'); INSERT INTO film VALUES(3,'ADAPTATION HOLES','A Astounding Reflection of a Lumberjack And a Car who must Sink a Lumberjack in A Baloon Factory'); INSERT INTO category VALUES(1,'Action','2006-02-14 20:46:27'); INSERT INTO category VALUES(2,'Animation','2006-02-14 20:46:27'); INSERT INTO category VALUES(3,'Children','2006-02-14 20:46:27'); INSERT INTO category VALUES(4,'Classics','2006-02-14 20:46:27'); INSERT INTO category VALUES(5,'Comedy','2006-02-14 20:46:27'); INSERT INTO category VALUES(6,'Documentary','2006-02-14 20:46:27'); INSERT INTO category VALUES(7,'Drama','2006-02-14 20:46:27'); INSERT INTO category VALUES(8,'Family','2006-02-14 20:46:27'); INSERT INTO category VALUES(9,'Foreign','2006-02-14 20:46:27'); INSERT INTO category VALUES(10,'Games','2006-02-14 20:46:27'); INSERT INTO category VALUES(11,'Horror','2006-02-14 20:46:27'); INSERT INTO film_category VALUES(1,6,'2006-02-14 21:07:09'); INSERT INTO film_category VALUES(2,11,'2006-02-14 21:07:09'); -- 左連線 + IS NULL SELECT F.film_id, F.title FROM film AS F LEFT JOIN film_category AS FC ON F.film_id = FC.film_id LEFT JOIN category AS C ON FC.category_id = C.category_id WHERE FC.film_id IS NULL
使用子查詢的方式找出屬於Action分類的所有電影對應的title,description
drop table if exists film ; drop table if exists category ; drop table if exists film_category ; CREATE TABLE IF NOT EXISTS film ( film_id smallint(5) NOT NULL DEFAULT '0', title varchar(255) NOT NULL, description text, PRIMARY KEY (film_id)); CREATE TABLE category ( category_id tinyint(3) NOT NULL , name varchar(25) NOT NULL, `last_update` timestamp, PRIMARY KEY ( category_id )); CREATE TABLE film_category ( film_id smallint(5) NOT NULL, category_id tinyint(3) NOT NULL, `last_update` timestamp); INSERT INTO film VALUES(1,'ACADEMY DINOSAUR','A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies'); INSERT INTO film VALUES(2,'ACE GOLDFINGER','A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China'); INSERT INTO film VALUES(3,'ADAPTATION HOLES','A Astounding Reflection of a Lumberjack And a Car who must Sink a Lumberjack in A Baloon Factory'); INSERT INTO category VALUES(1,'Action','2006-02-14 20:46:27'); INSERT INTO category VALUES(2,'Animation','2006-02-14 20:46:27'); INSERT INTO category VALUES(3,'Children','2006-02-14 20:46:27'); INSERT INTO category VALUES(4,'Classics','2006-02-14 20:46:27'); INSERT INTO category VALUES(5,'Comedy','2006-02-14 20:46:27'); INSERT INTO category VALUES(6,'Documentary','2006-02-14 20:46:27'); INSERT INTO film_category VALUES(1,1,'2006-02-14 21:07:09'); INSERT INTO film_category VALUES(2,1,'2006-02-14 21:07:09'); INSERT INTO film_category VALUES(3,6,'2006-02-14 21:07:09'); -- 子查詢 -- 第一步查詢分類型別為action的記錄,只取主鍵 SELECT category_id FROM category WHERE `name` = 'action' -- 第二步通過中間表獲取電影的主鍵列表 只取電影主鍵 SELECT film_id FROM film_category WHERE category_id = ( SELECT category_id FROM category WHERE `name` = 'action' ) -- 第三步 查詢電影表 巢狀上述的子查詢 SELECT `title`, `description` FROM film WHERE film_id IN ( SELECT film_id FROM film_category WHERE category_id = ( SELECT category_id FROM category WHERE `name` = 'action' ) )
建立一個actor表
-- 直接把題目的表格貼上過來改改就行了 CREATE TABLE `actor` ( actor_id smallint(5) not null comment '主鍵id', first_name varchar(45) not null comment '名字', last_name varchar(45) not null comment '姓氏', last_update date not null comment '日期' )
批量插入資料,不使用replace操作
對於表actor插入如下資料,如果資料已經存在,請忽略
(不支援使用replace操作)
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); insert into actor values ('3', 'WD', 'GUINESS', '2006-02-15 12:34:33'); # mysql中常用的三種插入資料的語句: # insert into表示插入資料,資料庫會檢查主鍵,如果出現重複會報錯; # replace into表示插入替換資料,需求表中有PrimaryKey, # 或者unique索引,如果資料庫已經存在資料,則用新資料替換,如果沒有資料效果則和insert into一樣; # insert ignore表示,如果中已經存在相同的記錄,則忽略當前新資料; insert ignore into actor values("3","ED","CHASE","2006-02-15 12:34:33");
對first_name建立唯一索引uniq_idx_firstname
針對如下表actor結構建立索引: (注:在 SQLite 中,除了重命名錶和在已有的表中新增列,ALTER TABLE 命令不支援其他操作, mysql支援ALTER TABLE建立索引) 對first_name建立唯一索引uniq_idx_firstname,對last_name建立普通索引idx_lastnameCREATE 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); -- ALTER TABLE 語法新增 ALTER TABLE `now-coder-sql`.`actor` ADD UNIQUE INDEX `UNIQ_IDX_FIRST_NAME`(`first_name`) USING BTREE;
ALTER TABLE `now-coder-sql`.`actor` ADD INDEX `IDX_LAST_NAME`(`last_name`) USING BTREE;
針對actor表建立檢視actor_name_view
actor表建立檢視actor_name_view,只包含first_name以及last_name兩列,並對這兩列重新命名,
first_name為first_name_v,last_name修改為last_name_v:
後臺會插入2條資料: insert into actor values ('1', 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'), ('2', 'NICK', 'WAHLBERG', '2006-02-15 12:34:33'); 然後列印檢視名字和插入的資料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); insert into actor values ('1', 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'), ('2', 'NICK', 'WAHLBERG', '2006-02-15 12:34:33'); -- 對查詢之前編寫一個檢視SQL建立語法 CREATE VIEW `now-coder-sql`.`actor_name_view` AS SELECT first_name AS `first_name_v`, last_name AS `last_name_v`, FROM actor; -- 呼叫檢視 SELECT * FROM actor_name_view
針對salaries表emp_no欄位建立索引idx_emp_no
針對salaries表emp_no欄位建立索引idx_emp_no,查詢emp_no為10005,使用強制索引。後臺會檢查是否使用強制索引
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`)); create index idx_emp_no on salaries(emp_no); -- 強制使用索引語法 SELECT * FROM salaries FORCE INDEX (idx_emp_no) WHERE emp_no = 10005
強制使用索引:
https://www.yangdx.com/2020/05/151.html
在last_update後面新增加一列名字為create_date
在last_update後面新增加一列名字為create_date, 型別為datetime, NOT NULL,預設值為'2020-10-01 00:00:00'
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); -- 指定欄位後面追加 ALTER TABLE actor ADD COLUMN `create_date` datetime NOT NULL DEFAULT '2020-10-01 00:00:00' AFTER `last_update` ;
構造一個觸發器audit_log
構造一個觸發器audit_log,在向employees_test表中插入一條資料的時候,觸發插入相關的資料到audit中。
後臺會往employees_test插入一條資料: INSERT INTO employees_test (ID,NAME,AGE,ADDRESS,SALARY)VALUES (1, 'Paul', 32, 'California', 20000.00 ); 然後從audit裡面使用查詢語句: select * from audit;drop table if exists audit; drop table if exists employees_test; CREATE TABLE employees_test( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL ); CREATE TABLE audit( EMP_no INT NOT NULL, NAME TEXT NOT NULL ); -- 建立表格 CREATE TRIGGER `audit_log` AFTER INSERT ON `employees_test` FOR EACH ROW INSERT INTO audit VALUES(NEW.ID, NEW.`NAME`); -- 插入測試 INSERT INTO employees_test (ID,NAME,AGE,ADDRESS,SALARY) VALUES (1, 'Paul', 32, 'California', 20000.00 );
在audit表上建立外來鍵約束,其emp_no對應employees_test表的主鍵id
後臺會判斷是否建立外來鍵約束,建立輸出1,沒建立輸出0drop table if exists audit; drop table if exists employees_test; CREATE TABLE employees_test( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL ); CREATE TABLE audit( EMP_no INT NOT NULL, create_date datetime NOT NULL ); -- 設定約束外來鍵,指定引用欄位 ALTER TABLE audit ADD CONSTRAINT FOREIGN KEY (emp_no) REFERENCES employees_test(id);
將所有獲取獎金的員工當前的薪水增加10%
請你寫出更新語句,將所有獲取獎金的員工當前的(salaries.to_date='9999-01-01')薪水增加10%。 (emp_bonus裡面的emp_no都是當前獲獎的所有員工,不考慮獲取的獎金的型別)。drop table if exists emp_bonus; drop table if exists `salaries`; create table emp_bonus( emp_no int not null, btype smallint not null ); CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` float(11,1) default NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`) ); insert into emp_bonus values(10001,1); INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22'); INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01'); -- 聯表更新 UPDATE `salaries` AS S JOIN `emp_bonus` AS B ON S.emp_no = B.emp_no SET S.salary = S.salary * 1.1 WHERE S.to_date = '9999-01-01'
將employees表中的所有員工的last_name和first_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 strings; CREATE TABLE strings( id int(5) NOT NULL PRIMARY KEY, string varchar(45) NOT NULL ); insert into strings values (1, '10,A,B'), (2, 'A,B,C,D'), (3, 'A,11,B,C,D,E'); -- 1、將引號替換成無字元 -- REPLACE(string, ',', '') -- 2、源字元長度獲取 -- LENGTH(string) -- 3、無引號字元長度 -- LENGTH( REPLACE(string, ',', '')) -- 4、引號的個數 = 源字元長度 - 無引號字元長度 -- LENGTH(string) - LENGTH( REPLACE(string, ',', '')) -- 5、最終SQL -- string長度減去 將逗號替換為空字串的長度 即是 逗號數量 SELECT id, LENGTH(string) - LENGTH( REPLACE(string, ',', '')) AS cnt FROM strings
獲取employees中的first_name
將employees中的first_name,並按照first_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'); -- 排序按 此欄位的最後兩個字元升序 SELECT `first_name` FROM `employees` ORDER BY RIGHT(`first_name`, 2) ASC -- 或者直接截取出來排序 SELECT `first_name` FROM `employees` ORDER BY SUBSTR(`first_name`, -2) ASC
按照dept_no進行彙總
dept_no進行彙總,屬於同一個部門的emp_no按照逗號進行連線,結果給出dept_no以及連接出的結果employeesdrop table if exists `dept_emp` ; 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`)); INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01'); INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01'); INSERT INTO dept_emp VALUES(10003,'d004','1995-12-03','9999-01-01'); INSERT INTO dept_emp VALUES(10004,'d004','1986-12-01','9999-01-01'); INSERT INTO dept_emp VALUES(10005,'d003','1989-09-12','9999-01-01'); INSERT INTO dept_emp VALUES(10006,'d002','1990-08-05','9999-01-01'); INSERT INTO dept_emp VALUES(10007,'d005','1989-02-10','9999-01-01'); INSERT INTO dept_emp VALUES(10008,'d005','1998-03-11','2000-07-31'); INSERT INTO dept_emp VALUES(10009,'d006','1985-02-18','9999-01-01'); INSERT INTO dept_emp VALUES(10010,'d005','1996-11-24','2000-06-26'); INSERT INTO dept_emp VALUES(10010,'d006','2000-06-26','9999-01-01'); -- 分組後再用 GROUP_CONCAT 分組合並處理 SELECT `dept_no`, GROUP_CONCAT(`emp_no`) AS `employees` FROM `dept_emp` GROUP BY `dept_no`
平均工資
查詢排除在職(to_date = '9999-01-01' )員工的最大、最小salary之後,其他的在職員工的平均工資avg_salary。
drop table if exists `salaries` ; CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` float(11,3) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`)); 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,'2001-08-02','9999-01-01'); INSERT INTO salaries VALUES(10003,43699,'2000-12-01','2001-12-01'); INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01'); INSERT INTO salaries VALUES(10004,70698,'2000-11-27','2001-11-27'); INSERT INTO salaries VALUES(10004,74057,'2001-11-27','9999-01-01'); -- SQL編寫思路 -- 1、查詢最大的和最小的記錄 -- 2、INNER JOIN 內連線 聯表取反 -- 3、補充WHERE條件 -- 4、對查詢欄位AVG -- 5、小數位過多,ROUND限制 SELECT ROUND( AVG(S.`salary`), 3) AS avg_salary FROM salaries AS S JOIN (SELECT * FROM salaries WHERE to_date = '9999-01-01' ORDER BY salary ASC LIMIT 1) AS MIN ON S.emp_no != MIN.emp_no JOIN (SELECT * FROM salaries WHERE to_date = '9999-01-01' ORDER BY salary DESC LIMIT 1) AS MAX ON S.emp_no != MAX.emp_no WHERE S.to_date = '9999-01-01'
分頁查詢employees表,每5行一頁,返回第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'); -- LIMIT X OFFSET Y -- X size 展示多少 -- Y offset 從哪條記錄開始 -- 如果不寫 OFFSET , 就反過來, X是偏移,Y是展示數 SELECT * FROM `employees` LIMIT 5 OFFSET 5
使用含有關鍵字exists查詢未分配具體部門的員工的所有資訊
drop table if exists employees; drop table if exists dept_emp; 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`)); 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`)); 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'); INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01'); INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01'); INSERT INTO dept_emp VALUES(10003,'d004','1995-12-03','9999-01-01'); INSERT INTO dept_emp VALUES(10004,'d004','1986-12-01','9999-01-01'); INSERT INTO dept_emp VALUES(10005,'d003','1989-09-12','9999-01-01'); INSERT INTO dept_emp VALUES(10006,'d002','1990-08-05','9999-01-01'); INSERT INTO dept_emp VALUES(10007,'d005','1989-02-10','9999-01-01'); INSERT INTO dept_emp VALUES(10008,'d005','1998-03-11','2000-07-31'); INSERT INTO dept_emp VALUES(10009,'d006','1985-02-18','9999-01-01'); INSERT INTO dept_emp VALUES(10010,'d005','1996-11-24','2000-06-26'); INSERT INTO dept_emp VALUES(10010,'d006','2000-06-26','9999-01-01'); -- 查詢存在 D表中關聯E表的記錄 -- 如果存在 關聯不到的記錄,觸發NOT EXISTS 條件 SELECT * FROM employees e WHERE NOT EXISTS ( SELECT emp_no FROM dept_emp d WHERE d.emp_no = e.emp_no );
刷題通過的題目排名
輸出通過的題目的排名,通過題目個數相同的,排名相同,此時按照id升序排列
drop table if exists passing_number; CREATE TABLE `passing_number` ( `id` int(4) NOT NULL, `number` int(4) NOT NULL, PRIMARY KEY (`id`)); INSERT INTO passing_number VALUES (1,4), (2,3), (3,3), (4,2), (6,4), (5,5); -- 8版本開窗函式解決 SELECT id, number, dense_rank() over ( ORDER BY number DESC ) AS t_rank FROM passing_number; -- 5版本解決辦法,找大於等於自己的SQL SELECT p1.id, p1.number, ( SELECT count( DISTINCT p2.number ) FROM passing_number AS p2 WHERE p2.number >= p1.number ) AS t_rank FROM passing_number AS p1 ORDER BY number DESC, id ASC
考試分數(二)
查詢使用者分數大於其所在工作(job)分數的平均分的所有grade的屬性,並且以id的升序排序
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), (9,'Java',12500); -- 先做平均分表,然後聯表計算 SELECT MAIN.* FROM `grade` AS MAIN JOIN ( SELECT `job`, AVG(`score`) AS `AVG_SCORE` FROM `grade` GROUP BY `job` ) AS AVG_TAB ON MAIN.`job` = AVG_TAB.`job` WHERE MAIN.`score` > AVG_TAB.`AVG_SCORE` ORDER BY MAIN.`id` ASC
課程訂單分析(二)
查詢在2025-10-15以後,
同一個使用者下單2個以及2個以上狀態為購買成功的C++課程或Java課程或Python課程的user_id,並且按照user_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,57,'Java','completed',1,'2025-10-24'), (7,557336,'C++','completed',1,'2025-10-25'); -- 主要是日期的查詢 SELECT `user_id` FROM `order_info` WHERE 1 = 1 AND `date` >= '2025-10-15' AND `status` = 'completed' AND `product_name` IN ('C++', 'Java', 'Python') GROUP BY `user_id` HAVING COUNT(`user_id`) > 1
課程訂單分析(三)
查詢在2025-10-15以後,
同一個使用者下單2個以及2個以上狀態為購買成功的C++課程或Java課程或Python課程的訂單資訊,並且按照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,57,'Java','completed',1,'2025-10-24'), (7,557336,'C++','completed',1,'2025-10-25'); -- 先篩選買了兩套以上的,再看其他條件 SELECT * FROM `order_info` WHERE `user_id` IN ( SELECT `user_id` FROM `order_info` GROUP BY `user_id` HAVING COUNT(`user_id`) > 1 ) AND `date` >= '2025-10-15' AND `status` = 'completed' AND `product_name` IN ('C++', 'Java', 'Python') ORDER BY `id` ASC
課程訂單分析(六)
查詢在2025-10-15以後,
同一個使用者下單2個以及2個以上狀態為購買成功的C++課程或Java課程或Python課程的訂單id,
是否拼團以及客戶端名字資訊,最後一列如果是非拼團訂單,則顯示對應客戶端名字,如果是拼團訂單,則顯示NULL,並且按照order_info的id升序排序
drop table if exists order_info; drop table if exists client; 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, is_group_buy 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 order_info VALUES (1,557336,'C++','no_completed',1,'2025-10-10','No'), (2,230173543,'Python','completed',2,'2025-10-12','No'), (3,57,'JS','completed',0,'2025-10-23','Yes'), (4,57,'C++','completed',3,'2025-10-23','No'), (5,557336,'Java','completed',0,'2025-10-23','Yes'), (6,57,'Java','completed',1,'2025-10-24','No'), (7,557336,'C++','completed',0,'2025-10-25','Yes'); INSERT INTO client VALUES (1,'PC'), (2,'Android'), (3,'IOS'), (4,'H5') -- 1、用上一題的作為主表左連線客戶端表,存在沒有客戶端的情況 -- 2、然後對NULL的客戶端名稱進行 空處理 SELECT MAIN.id, MAIN.is_group_buy, IFNULL(client.`name`, 'None') AS `client_name` FROM (SELECT * FROM `order_info` WHERE `user_id` IN ( SELECT `user_id` FROM `order_info` GROUP BY `user_id` HAVING COUNT(`user_id`) > 1 ) AND `date` >= '2025-10-15' AND `status` = 'completed' AND `product_name` IN ('C++', 'Java', 'Python') ORDER BY `id` ASC) AS MAIN LEFT JOIN client ON client.id = MAIN.client_id
實習廣場投遞簡歷分析(二)
查詢在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,'C++','2025-01-03',54), (5,'Python','2025-01-03',43), (6,'Java','2025-01-03',41), (7,'Java','2025-02-03',24), (8,'C++','2025-02-03',23), (9,'Python','2025-02-03',34), (10,'Java','2025-02-04',42), (11,'C++','2025-02-04',45), (12,'Python','2025-02-04',59), (13,'Python','2025-03-04',54), (14,'C++','2025-03-04',65), (15,'Java','2025-03-04',92), (16,'Python','2025-03-05',34), (17,'C++','2025-03-05',34), (18,'Java','2025-03-05',34), (19,'Python','2026-01-04',230), (20,'C++','2026-02-06',231); -- 主要是對記錄進行兩個欄位的分組,和月份的處理 SELECT job, date_format( date, '%Y-%m' ) AS mon, sum( num ) AS cnt FROM resume_info WHERE YEAR(date) = 2025 GROUP BY job, mon ORDER BY mon DESC, cnt DESC;
最差是第幾名(一)
如果一個學生知道了自己綜合成績以後,最差是排第幾名? 結果按照grade升序排序
drop table if exists class_grade; CREATE TABLE class_grade ( grade varchar(32) NOT NULL, number int(4) NOT NULL ); INSERT INTO class_grade VALUES ('A',2), ('D',1), ('C',2), ('B',2); -- 查詢 SELECT c1.grade, SUM( c2.number ) AS t_rank FROM class_grade c1 CROSS JOIN class_grade c2 ON c1.grade >= c2.grade GROUP BY c1.grade ORDER BY c1.grade ASC;
獲得積分最多的人(一)
查詢積分增加最高的使用者的名字,以及他的總積分是多少(此題資料保證積分最高的使用者有且只有1個)
drop table if exists user; drop table if exists grade_info; CREATE TABLE user ( id int(4) NOT NULL, name varchar(32) NOT NULL ); CREATE TABLE grade_info ( user_id int(4) NOT NULL, grade_num int(4) NOT NULL, type varchar(32) NOT NULL ); INSERT INTO user VALUES (1,'tm'), (2,'wwy'), (3,'zk'), (4,'qq'), (5,'lm'); INSERT INTO grade_info VALUES (1,3,'add'), (2,3,'add'), (1,1,'add'), (3,3,'add'), (4,3,'add'), (5,3,'add'); -- 查詢最大的那一個,然後聯表獲取 SELECT `USER`.`NAME`, t.grade_sum FROM ( SELECT user_id, 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
商品交易(網易校招筆試真題)
查詢購買個數超過20,質量小於50的商品,按照商品id升序排序
CREATE TABLE `goods` ( `id` int(11) NOT NULL, `name` varchar(10) DEFAULT NULL, `weight` int(11) NOT NULL, PRIMARY KEY (`id`) ); CREATE TABLE `trans` ( `id` int(11) NOT NULL, `goods_id` int(11) NOT NULL, `count` int(11) NOT NULL, PRIMARY KEY (`id`) ); insert into goods values(1,'A1',100); insert into goods values(2,'A2',20); insert into goods values(3,'B3',29); insert into goods values(4,'T1',60); insert into goods values(5,'G2',33); insert into goods values(6,'C0',55); insert into trans values(1,3,10); insert into trans values(2,1,44); insert into trans values(3,6,9); insert into trans values(4,1,2); insert into trans values(5,2,65); insert into trans values(6,5,23); insert into trans values(7,3,20); insert into trans values(8,2,16); insert into trans values(9,4,5); insert into trans values(10,1,3); -- 聯表之後再進行分組查詢 SELECT g.id, g.NAME, g.weight, sum( t.count ) ss FROM trans t LEFT JOIN goods g ON t.goods_id = g.id GROUP BY t.goods_id HAVING ( ss > 20 AND g.weight < 50 ) ORDER BY g.id ASC