当前位置: 首页 > article >正文

mysql经典试题共34题

1、准备数据


--  drop
drop table if exists dept;
drop table if exists emp; 
drop table if exists salgrade;

--  CREATE
CREATE TABLE `dept` (
  `deptno` int NOT NULL COMMENT '部门编号',
  `dname` varchar(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '部门名称',
  `loc` varchar(13) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '部门位置',
  PRIMARY KEY (`deptno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `emp` (
  `empno` int NOT NULL COMMENT '员工编号',
  `ename` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '员工名字',
  `job` varchar(9) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '员工岗位',
  `mgr` int DEFAULT NULL COMMENT '上级领导编号',
  `hiredate` date DEFAULT NULL COMMENT '入职日期',
  `sal` double(7,2) DEFAULT NULL COMMENT '月薪',
  `comm` double(7,2) DEFAULT NULL COMMENT '补助',
  `deptno` int DEFAULT NULL COMMENT '部门编号',
  PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `salgrade` (
  `grade` int DEFAULT NULL COMMENT '薪水等级',
  `losal` int DEFAULT NULL COMMENT '最低薪水',
  `hisal` int DEFAULT NULL COMMENT '最高薪水'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

--  INSERT
INSERT INTO `dept` (`deptno`, `dname`, `loc`) VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO `dept` (`deptno`, `dname`, `loc`) VALUES (20, 'RESEARCHING', 'DALLAS');
INSERT INTO `dept` (`deptno`, `dname`, `loc`) VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO `dept` (`deptno`, `dname`, `loc`) VALUES (40, 'OPERATIONS', 'BOSTON');

INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7369, 'SIMITH', 'CLERK', 7902, '1980-12-17', 800.00, NULL, 20);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600.00, 300.00, 30);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250.00, 500.00, 30);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975.00, NULL, 20);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250.00, 1400.00, 30);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850.00, NULL, 30);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450.00, NULL, 10);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000.00, NULL, 20);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000.00, NULL, 10);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500.00, NULL, 30);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100.00, NULL, 20);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950.00, NULL, 30);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000.00, NULL, 20);
INSERT INTO `emp` (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`) VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300.00, NULL, 10);

INSERT INTO `salgrade` (`grade`, `losal`, `hisal`) VALUES (1, 700, 1200);
INSERT INTO `salgrade` (`grade`, `losal`, `hisal`) VALUES (2, 1201, 1400);
INSERT INTO `salgrade` (`grade`, `losal`, `hisal`) VALUES (3, 1401, 2000);
INSERT INTO `salgrade` (`grade`, `losal`, `hisal`) VALUES (4, 2001, 3000);
INSERT INTO `salgrade` (`grade`, `losal`, `hisal`) VALUES (5, 3001, 5000);

2、试题与解答

-- 经典面试题
-- 表:dept(部门)、emp(员工)、salgrade(薪水等级)

-- 1、取得每个部门最高薪水的人员名称
-- (1)取得每个部门最高薪水
	select deptno, max(sal) MAXSAL from emp GROUP BY deptno;
	-- (2)条件:部门名称和薪水
	select t.deptno, e.ename, t.MAXSAL from (select deptno, max(sal) MAXSAL from emp GROUP BY deptno) t 
	LEFT JOIN emp e ON e.deptno = t.deptno and e.sal = t.MAXSAL ORDER BY t.deptno;

-- 2、哪些人的薪水在部门平均薪水之上
-- (1) 部门平均薪水
	select deptno, AVG(sal) from emp GROUP BY deptno;
-- (2) 查询哪些人 条件:部门编号和薪水
	select e.ename, e.sal, t.deptno, t.AVGSAL
	from emp e 
	JOIN (select deptno, AVG(sal) AVGSAL from emp GROUP BY deptno) t on e.deptno = t.deptno and e.sal > t.AVGSAL
	ORDER BY t.deptno;

-- 3、查各部门平均薪水等级
-- 先查部门平均薪水,再查等级
	select t.deptno, t.AVGSAL, s.*
	from salgrade s
	JOIN (select e.deptno, AVG(e.sal) AVGSAL from emp e GROUP BY e.deptno) t
	on t.AVGSAL between s.losal and s.hisal
	ORDER BY t.deptno; 
	
-- 4、不准用组函数,取得最高薪水(给出两种解决方案)
-- 5、取得平均薪水最高的部门编号(至少两个方案)
-- 6、取得平均薪水最高的部门的部门名称
-- (1)先查每个部门的平均薪水
select deptno, AVG(sal) AVGSAL from emp GROUP BY deptno ORDER BY AVGSAL desc LIMIT 0,1;
-- (2)查薪水最高的部门
select d.deptno, d.dname, t.AVGSAL from dept d,(select deptno, AVG(sal) AVGSAL from emp GROUP BY deptno ORDER BY AVGSAL desc LIMIT 1) t
where d.deptno = t.deptno;
-- 7、求平均薪水等级最高的部门的名称
-- (1)每个部门的平均薪水
select e.deptno, d.dname, AVG(e.sal) AVGSAL from emp e, dept d where e.deptno = d.deptno GROUP BY e.deptno, d.dname;
-- (2) 每个部门的薪水等级
select t.deptno, t.dname, s.grade
from (select e.deptno, d.dname, AVG(e.sal) AVGSAL from emp e, dept d where e.deptno = d.deptno GROUP BY e.deptno, d.dname) t, salgrade s 
where t.AVGSAL between s.losal and s.hisal;
-- (3)查最高的部门薪水等级
select max(s.grade) maxgrade from salgrade s 
JOIN (select e.deptno, d.dname, AVG(e.sal) AVGSAL from emp e, dept d where e.deptno = d.deptno GROUP BY e.deptno, d.dname) t 
on t.AVGSAL between s.losal and s.hisal;
-- (4)薪水等级最高的部门的名称(第二个条件与第三个条件即:最高等级有几个部门)
select t1.*,t2.maxgrade
from (select t.deptno, t.dname, s.grade 
			from (select e.deptno, d.dname, AVG(e.sal) AVGSAL from emp e, dept d where e.deptno = d.deptno GROUP BY e.deptno, d.dname) t, 			salgrade s where t.AVGSAL between s.losal and s.hisal) t1 
JOIN (select max(s.grade) maxgrade from salgrade s 
			JOIN (select e.deptno, d.dname, AVG(e.sal) AVGSAL from emp e, dept d where e.deptno = d.deptno GROUP BY e.deptno, d.dname) t 
			on t.AVGSAL between s.losal and s.hisal) t2 
on t1.grade = t2.maxgrade;
-- 8、取得比普通员工的最高薪水还要高的经理人姓名
select COUNT(1) from emp;
-- (1) 查到所有经理人
select DISTINCT mgr from emp where mgr is not NULL;
-- (2) 查所有的员工(即:非经理人、非king)的最大工资
select max(sal) from emp where empno not in (select DISTINCT mgr from emp where mgr is not NULL);
-- (3) 取得经理人姓名
select e.* from emp e JOIN (select max(sal) maxsal from emp where empno not in (select DISTINCT mgr from emp where mgr is not NULL)) t on e.sal > t.maxsal;
-- 9、取得薪水最高的前五名员工
-- 10、取得薪水最高的第六到第十名员工
select * from emp ORDER BY sal desc;
/*
SELECT * FROM table_name LIMIT offset, row_count;
offset:表示跳过的行数,从0开始计数。
row_count:表示返回的行数。
如果只指定一个参数,LIMIT 默认从第0行开始返回指定的行数。
*/
select * from emp ORDER BY sal desc limit 5,5;
-- 11、取得最后入职的五名员工
-- 12、取得每个薪水等级有多少员工
select s.grade,count(1) from emp e,salgrade s where e.sal between s.losal and s.hisal GROUP BY s.grade;
-- 13、学生、课程、学生课程表   -- 略
-- 14、列出所有员工及领导的名字
select e1.empno "员工编号",e1.ename "员工姓名", e1.mgr "经理编号", e2.ename "经理姓名" from emp e1 
LEFT JOIN (select * from emp) e2 on e1.mgr = e2.empno;
-- 15、列出受雇佣日期早于其直接上级的所有员工编号、姓名、部门名称
-- (1) 找出受雇佣日期早于其直接上级的所有员工编号、姓名
select e1.empno, e1.ename,e1.deptno from emp e1 LEFT JOIN emp e2 on e1.mgr = e2.empno where e1.hiredate < e2.hiredate;
-- (2)找出部门名称(与dept表连接)
select t.empno, t.ename, d.dname from dept d 
JOIN (select e1.empno, e1.ename,e1.deptno from emp e1 LEFT JOIN emp e2 on e1.mgr = e2.empno
			where e1.hiredate < e2.hiredate) t 
on d.deptno = t.deptno;
-- 16、列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门
select e.*,d.dname from emp e RIGHT JOIN dept d on e.deptno = d.deptno;
-- 17、列出至少有5个员工的所有部门(having对分组后的数据过滤:查询每组的记录总数)
select d.dname, count(1) count from emp e JOIN dept d on e.deptno = d.deptno GROUP BY d.dname HAVING count < 5;
-- 18、列出薪水比"SIMITH"多的所有员工信息
select e.* from emp e where e.sal > (select sal FROM emp where ename='SIMITH');
-- 19、列出所有"CLERK"(办事员)的姓名及其部门名称、部门人数
select e.ename,d.deptno,d.dname from (select * from emp where job = 'CLERK') e JOIN dept d on e.deptno = d.deptno;

select deptno, count(1) from emp GROUP BY deptno; 

select e.*,t.deptnum from (select e.ename,d.deptno,d.dname from (select * from emp where job = 'CLERK') e JOIN dept d on e.deptno = d.deptno) e left JOIN (select deptno, count(1) deptnum from emp GROUP BY deptno) t on e.deptno = t.deptno;
-- 20、列出最低薪水大于1500的各种工作及从事此工作的全部雇员人数
-- WHERE子句用于在查询时对数据行进行过滤,它在分组操作之前执行。因此,WHERE子句中不能直接使用分组后的聚合结果。
-- HAVING子句的作用是在分组后对分组结果进行过滤
select job, min(sal) minsal, count(job) total from emp GROUP BY job HAVING minsal > 1500;
-- 21、列出在部门"SALES"《销售部》工作的员工的姓名,假定不知道销售部门的部门编号
select deptno,dname from dept where dname = 'SALES';
select e.ename from emp e where e.deptno = (select deptno from dept where dname = 'SALES');
-- 22、列出薪金高于公司平均薪金的所有员工,所在部门、上级领导、雇员的工资等级
select e.*,d.dname,e2.ename "上级领导", s.grade from emp e 
JOIN dept d on e.deptno = d.deptno
LEFT JOIN emp e2 on e.mgr = e2.empno
JOIN salgrade s on e.sal between s.losal and s.hisal
where e.sal > (select avg(sal) from emp);
-- 23、列出与"SCOTT"从事相同工作的所有员工及部门名称
select e.job,d.dname from emp e JOIN dept d on e.deptno = d.deptno and e.ename='SCOTT';
select e.*, t.dname from emp e JOIN (select e.job,d.dname from emp e JOIN dept d on e.deptno = d.deptno and e.ename='SCOTT') t 
on e.job = t.job;
-- 24、列出薪金等于部门30中员工的薪金的其他员工的姓名和薪金
select sal from emp where deptno=30;
-- 25、列出薪金高于在部门30工作的所有员工的薪金的员工姓名、薪金、部门名称
select e.ename,e.sal,d.dname from emp e
JOIN dept d on e.deptno = d.deptno
where e.sal > (select max(sal) from emp where deptno=30);
-- 26、列出在每个部门工作的员工数量、平均工资和平均服务期限
SELECT
	d.deptno,
	count( e.deptno ),
	IFNULL( avg( e.sal ), 0 ),
	IFNULL(avg(( TO_DAYS( NOW()) - TO_DAYS( hiredate )) / 365 ) , 0)
FROM
	emp e
	RIGHT JOIN dept d ON e.deptno = d.deptno 
GROUP BY
	d.deptno;
-- 27、列出所有员工的姓名、部门名称和工资
-- 28、列出所有部门的详细信息和人数
select deptno,count(empno) from emp GROUP BY deptno;
select d.*,IFNULL(t.total,0) from dept d left JOIN (select deptno,count(empno) total from emp GROUP BY deptno) t on d.deptno = t.deptno;
-- 29、列出各种工作的最低工资及从事此工作的雇员姓名
select job,min(sal) minsal from emp GROUP BY job;
select e.job,e.minsal,e2.ename from (select job,min(sal) minsal from emp GROUP BY job) e 
JOIN emp e2 on e.minsal = e2.sal; 
-- 30、列出每个部门MANAGER的最低薪资
select * from emp where job="MANAGER";
select min(sal) minsal,deptno from emp where job="MANAGER" group by deptno;
-- 31、列出所有员工的年工资,按年薪从低到高排序
select empno,ename,sal,comm,(sal + IFNULL(comm, 0)) * 12 AS "年薪" from emp ORDER BY 年薪;
-- 32、求出员工领导的薪水超过3000的员工名称和领导名称
select e1.empno,e1.ename,e1.sal, e2.empno "领导编号",e2.sal "领导薪水",e2.ename "领导姓名" 
from emp e1 JOIN emp e2 on e1.mgr = e2.empno and e2.sal > 3000;
-- 33、求部门名称中带"S"字符的部门员工的工资合计、部门人数
select deptno from dept where dname like "%S%";
select t.deptno,IFNULL(sum(e.sal),0),count(e.empno) from emp e RIGHT JOIN (select deptno from dept where dname like "%S%") t on e.deptno = t.deptno GROUP BY t.deptno;
-- 34、给任职日期超过30年的员工加薪10%
select empno,sal from emp where ((TO_DAYS(NOW()) - TO_DAYS(hiredate))/365) > 30;
drop table if EXISTS emp_bak;
create table emp_bak as select * from emp;
update emp_bak set sal = (sal*1.1) where (TO_DAYS(NOW()) - TO_DAYS(hiredate))/365 > 30;


参考:SQL经典训练试题_哔哩哔哩_bilibili


http://www.kler.cn/a/578127.html

相关文章:

  • UDP协议和报文格式
  • Redis | 哨兵 Sentinel
  • Java高频面试之集合-07
  • LeetCode 90: 子集 II
  • 【后端开发】go-zero微服务框架实践(goland框架对比,go-zero开发实践,文件上传问题优化等等)
  • Docker基础-项目部署流程解析
  • 07 HarmonyOS NEXT 仿uv-ui Tag组件开发教程系列(一)
  • VUE3开发-9、axios前后端跨域问题解决方案
  • K8s 1.27.1 实战系列(三)安装网络插件
  • spring Web Mvc 介绍
  • SpireCV荣获Gitee 最有价值开源项目称号
  • 中国嵌入式单片机就业形势分析
  • 【Redis】终极缓存四连杀:缓存预热、缓存击穿、缓存穿透、缓存雪崩,真的懂了吗?
  • C++ 构造函数、析构函数和复制构造函数
  • 《深入浅出数据索引》- 公司内部培训课程笔记
  • JQuery 语法 $
  • python 程序一次启动有两个进程的问题(flask)
  • Vue.js + Element Plus:擦出高效开发的火花
  • JAVA实战开源项目:在线音乐网站(Vue+SpringBoot) 附源码
  • 芯麦GC4938:高功率电机驱动芯片,全面替代A4938/Allegro的国产优选方案