(MySQL)SQL语句练习题【老杜34题】

文章目录

一、建表语句

-- 1、部门表
CREATE TABLE DEPT ( 
	DEPTNO INT ( 2 ) NOT NULL, 
	DNAME VARCHAR ( 14 ), 
	LOC VARCHAR ( 13 ), 
	PRIMARY KEY ( DEPTNO ) );
	
-- 2、员工表
CREATE TABLE EMP (
	EMPNO INT ( 4 ) NOT NULL,
	ENAME VARCHAR ( 10 ),
	JOB VARCHAR ( 9 ),
	MGR INT ( 4 ),
	HIREDATE DATE DEFAULT NULL,
	SAL DOUBLE ( 7, 2 ),
	COMM DOUBLE ( 7, 2 ),
	PRIMARY KEY ( EMPNO ),
	DEPTNO INT ( 2 ) 
	
-- 3、薪水等级表
CREATE TABLE SALGRADE ( 
	GRADE INT, 
	LOSAL INT, 
	HISAL INT );
);

二、插入测试数据

-- 1、插入部门表数据
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 10, 'ACCOUNTING', 'NEW YORK'); 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 20, 'RESEARCH', 'DALLAS'); 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 30, 'SALES', 'CHICAGO'); 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 40, 'OPERATIONS', 'BOSTON'); 
commit;
 
 -- 2、插入员工表数据
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7369, 'SMITH', 'CLERK', 7902,  '1980-12-17', 800, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7499, 'ALLEN', 'SALESMAN', 7698,  '1981-02-20', 1600, 300, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7521, 'WARD', 'SALESMAN', 7698,  '1981-02-22'
, 1250, 500, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7566, 'JONES', 'MANAGER', 7839,  '1981-04-02'
, 2975, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7654, 'MARTIN', 'SALESMAN', 7698,  '1981-09-28'
, 1250, 1400, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7698, 'BLAKE', 'MANAGER', 7839,  '1981-05-01'
, 2850, NULL, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7782, 'CLARK', 'MANAGER', 7839,  '1981-06-09'
, 2450, NULL, 10); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7788, 'SCOTT', 'ANALYST', 7566,  '1987-04-19'
, 3000, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7839, 'KING', 'PRESIDENT', NULL,  '1981-11-17'
, 5000, NULL, 10); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7844, 'TURNER', 'SALESMAN', 7698,  '1981-09-08'
, 1500, 0, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7876, 'ADAMS', 'CLERK', 7788,  '1987-05-23'
, 1100, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7900, 'JAMES', 'CLERK', 7698,  '1981-12-03'
, 950, NULL, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7902, 'FORD', 'ANALYST', 7566,  '1981-12-03'
, 3000, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,DEPTNO ) VALUES ( 7934, 'MILLER', 'CLERK', 7782,  '1982-01-23'
, 1300, NULL, 10); 
commit;
 
 -- 3、插入薪水等级表数据
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, 9999); 
commit;

三、练习题

1、取得每个部门最高薪水的人员名称

SELECT
	ename 
FROM
	emp e
	JOIN ( SELECT deptno, max( sal ) sal FROM emp GROUP BY deptno ) a ON e.deptno = a.deptno 
	AND e.sal = a.sal

2、哪些人的薪水在部门的平均薪水之上(△)

SELECT
	e.ename,
	e.sal,
	a.* 
FROM
	emp e
	JOIN ( SELECT deptno, avg( sal ) avgSal FROM emp GROUP BY deptno ) a ON e.deptno = a.deptno 
	AND e.sal > a.avgSal

3、取得部门中(所有人的)平均的薪水等级

-- 平均的薪水等级:先计算每一个薪水的等级,然后找出薪水等级的平均值。
-- 平均薪水的等级:先计算平均薪水,然后找出每个平均薪水的等级值。
-- 第一步:获取每个人的薪水等级
-- 第二步:基于以上的结果继续按照deptno分组,求grade的平均值
SELECT
	e.deptno,
	avg( s.grade ) 
FROM
	emp e
	JOIN salgrade s ON e.sal BETWEEN s.losal 
	AND s.hisal 
GROUP BY
	e.deptno

4、不准用组函数(max),取得最高薪水(至少两种解决方案)

-- 第一种方案:sal降序,limit 
select sal from emp order by sal desc limit 1
-- 第二种方案:
select max(sal) from emp;
-- 第三种方案:
select sal from emp where sal not in(
select distinct a.sal from emp a 
join emp b on a.sal <b.sal )

5、取得平均薪水最高的部门的部门编号(至少两种解决方案)

第一种方案:降序取第一个
SELECT
	a.deptno 
FROM
	( SELECT deptno, avg( sal ) sal FROM emp GROUP BY deptno ) a 
ORDER BY
	sal DESC 
	LIMIT 1
第二种方案:max
SELECT
	a.deptno,
	max( a.sal ) maxSal 
FROM
	( SELECT deptno, avg( sal ) sal FROM emp GROUP BY deptno ) a

6、取得平均薪水最高的部门的部门名称

SELECT
	d.dname,
	avg( e.sal ) avgSal 
FROM
	emp e
	LEFT JOIN dept d ON e.deptno = d.deptno 
GROUP BY
	e.deptno 
ORDER BY
	avgSal DESC 
	LIMIT 1

7、求平均薪水的等级最低的部门的部门名称(△)

select a.*,s.grade from 
(select d.dname,avg(sal) avgSal from emp e
left join dept d on e.deptno = d.deptno
group by d.dname) a  join salgrade s on a.avgSal between s.losal and s.hisal
where grade =
(select grade from salgrade 
where (select avg(sal) avgSal from emp group by deptno  order by avgSal asc limit 1) between losal and hisal)

8、取得比普通员工(员工代码没有在mgr字段上出现的)的最高薪水还要高的领导人姓名(△)

-- 比普通员工的最高薪水还要高的一定是领导!√
-- not in在使用的时候,后面小括号中记的排除null
SELECT ename, sal FROM emp WHERE sal > (
	SELECT
		max( sal ) 
	FROM
		emp 
	WHERE
		empno NOT IN ( SELECT DISTINCT mgr FROM emp WHERE mgr IS NOT NULL ) 
	)

9、取得薪水最高的前五名员工

select ename,sal from emp
order by sal desc
limit 5

10、取得薪水最高的第六到第十名员工

select ename,sal from emp
order by sal desc
limit 5,5

11、取得最后入职的 5 名员工日期

日期也可以降序,升序

select hiredate from emp 
order by hiredate desc
limit 5

12、取得每个薪水等级有多少员工

select a.grade,count(a.ename) num from 
(select e.ename,e.sal,s.grade from emp e
left join salgrade s on e.sal between s.losal and s.hisal)a 
group by a.grade

13、面试题略过

14、列出所有员工及领导的姓名

select e.ename,m.ename leader from emp e 
left join emp m on e.mgr = m.empno

15、列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称

select e.ename '员工',e.HIREDATE,m.ename '领导',m.hiredate,d.dname from emp e
left join emp m on e.mgr = m.empno
left join dept d on e.deptno = d.deptno 
where e.hiredate < m.HIREDATE

16、 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门

select d.dname,e.empno,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm from dept d
left join emp e on d.deptno = e.deptno 

17、列出至少有 5 个员工的所有部门

select deptno,count(empno) num from emp
group by deptno 
having num>=5
select deptno num from emp
group by deptno 
having count(*)>=5

18、列出薪金比"SMITH" 多的所有员工信息

select e.ename,e.job,e.mgr,e.hiredate,sal,deptno from emp  e 
where sal> (select sal from emp where ename = 'SMITH')

19、 列出所有"CLERK"( 办事员) 的姓名及其部门名称, 部门的人数

select a.ename,a.dname,b.num from 
(select e.ename,e.deptno,d.dname from emp e
left join dept d on e.deptno = d.deptno
where e.job = 'CLERK') a left join 
(select deptno,count(ename) num from emp
group by deptno) b on a.deptno = b.deptno 

20、列出最低薪金大于 1500 的各种工作及从事此工作的全部雇员人数,按照工作岗位分组求最小值(△)

select job,count(*) from emp group by job having min(sal) > 1500;

21、列出在部门"SALES"< 销售部> 工作的员工的姓名,假定不知道销售部的部门编号

select ename from emp e
left join dept d on e.deptno = d.deptno
where d.dname ='SALES'

select ename from emp 
where deptno =(select deptno from dept where dname ='SALES')

22、列出薪金高于公司平均薪金的所有员工, 所在部门,上级领导,雇员的工资等级

select e.ename '员工',d.dname, m.ename '领导',s.grade from emp e
left join dept d on e.deptno = d.deptno 
left join emp m on e.mgr = m.empno
left join salgrade s on e.sal BETWEEN s.LOSAL and s.hisal
where e.sal> (select avg(sal) avgSal from emp )

23、 列出与"SCOTT" 从事相同工作的所有员工及部门名称

select e.ename,d.dname
from emp e
left join dept d on e.deptno = d.deptno
where e.job in (select job from emp
where ename = 'SCOTT') and e.ename <> 'SCOTT'

24、列出薪金等于部门 30 中员工的薪金的其他员工的姓名和薪金

select ename,sal,deptno from emp 
where deptno != 30 
and sal in 
(select distinct sal from emp 
where deptno =30)  

25、列出薪金高于在部门 30 工作的所有员工的薪金的员工姓名和薪金、部门名称

select e.ename,e.sal,d.dname from emp e
left join dept d on  e.deptno = d.deptno
where  e.sal >
(select max(sal) from emp where deptno =30) 

26、列出在每个部门工作的员工数量, 平均工资和平均服务期限(△)

-- 在mysql当中怎么计算两个日期的"年差",差了多少年:TimeStampDiff(间隔类型,前一个日期,后一个日期)
-- TimeStampDiff(YEAR,hiredate,now())
-- 间隔类型:SECOND 秒,MINUTE 分钟,HOUR 小时,DAY 天,WEEK 星期,MONTH 月,QUARTER 季度,YEAR 年
select d.*,count(e.ename) number,ifnull(avg(sal),0) avgSal,ifnull(avg(TimeStampDiff(YEAR,hiredate,now())),0) avgServiceTime from dept d
left join emp e on d.deptno = e.deptno 
group by d.deptno,d.dname,d.loc

27、列出所有员工的姓名、部门名称和工资

select e.ename,d.dname,e.sal from emp e 
left join dept d on e.deptno = d.deptno

28、列出所有部门的详细信息和人数

select d.deptno,d.dname,count(ename) num from dept d
left join emp e on d.deptno = e.deptno
GROUP BY d.deptno

29、列出各种工作的最低工资及从事此工作的雇员姓名

select e.ename,a.* from emp e
 join (select job,min(sal) lowSal
from emp 
group by job) a on e.job = a.job and e.sal = a.lowSal

30、列出各个部门的MANAGER(领导)的最低薪金

select deptno,min(sal) as minSal from emp
where job ='MANAGER'
GROUP BY deptno

31、列出所有员工的年工资, 按年薪从低到高排序

SELECT
	ename,(
	sal + ifnull( comm, 0 ))* 12 AS yearSal 
FROM
	emp 
ORDER BY
	yearSal

32、求出员工领导的薪水超过3000的员工名称与领导

SELECT
	e.ename,
	m.ename leader_name 
FROM
	emp e
	JOIN emp m ON e.mgr = m.empno 
WHERE
	m.sal > 3000

33、求出部门名称中, 带’S’字符的部门员工的工资合计、部门人数

SELECT
	d.deptno,
	d.dname,
	ifnull( sum( e.sal ), 0 ) sumSal,
	count( e.ename ) num 
FROM
	emp e
	RIGHT JOIN dept d ON e.deptno = d.deptno 
WHERE
	d.dname LIKE '%S%' 
GROUP BY
	d.deptno,
	d.dname

34、给任职日期超过 30 年的员工加薪 10%

update emp set sal = sal * 1.1 where timeStampDiff(YEAR,hiredate,now()) >30

四、视频链接

https://www.bilibili.com/video/BV1Vy4y1z7EX

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值