34道经典SQL试题(上)

1.取得每个部门最高薪水的人员名称
第一步 求出每个部门的最高薪水

select 
	e.deptno,max(e.sal) as maxsal
from
	emp e
group by
	e.deptno;
+--------+---------+
| deptno | maxsal  |
+--------+---------+
|     20 | 3000.00 |
|     30 | 2850.00 |
|     10 | 5000.00 |
+--------+---------+
将以上查询结果当成一个临时表t(deptno,maxsal)
select 
	e.deptno,max(e.sal) as maxsal
from
	emp e
group by
	e.deptno;

select 
	e.deptno,e.ename,t.maxsal,e.sal
from
	(select 
	e.deptno,max(e.sal) as maxsal
from
	emp e
group by
	e.deptno
	)t
join
	emp e
on 
	t.deptno = e.deptno
where
	t.maxsal =  e.sal
order by
	e.deptno;
+--------+-------+---------+---------+
| deptno | ename | maxsal  | sal     |
+--------+-------+---------+---------+
|     10 | KING  | 5000.00 | 5000.00 |
|     20 | SCOTT | 3000.00 | 3000.00 |
|     20 | FORD  | 3000.00 | 3000.00 |
|     30 | BLAKE | 2850.00 | 2850.00 |
+--------+-------+---------+---------+

2.那些人的薪水在部门平均薪水之上
第一步:求出每个部门的平均薪水

select
	e.deptno,avg(e.sal) as avgsal
from
	emp e
group by
	e.deptno;
	deptno	avgsal
+--------+-------------+
| deptno | avgsal      |
+--------+-------------+
|     20 | 2175.000000 |
|     30 | 1566.666667 |
|     10 | 2916.666667 |
+--------+-------------+
将以上查询结果当成临时表t(depntno,avgsal
select
	  t.deptno,e.ename
from
	(select
	e.deptno,avg(e.sal) as avgsal
from
	emp e
group by
	e.deptno)t
join
	emp e
on
	e.deptno = t.deptno
where
	e.sal>t.avgsal
order by
	e.deptno;
+--------+-------+
| deptno | ename |
+--------+-------+
|     10 | KING  |
|     20 | JONES |
|     20 | SCOTT |
|     20 | FORD  |
|     30 | ALLEN |
|     30 | BLAKE |
+--------+-------+

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

select
	t.deptno,t.avgsal,s.grade
from
	 (select
	e.deptno,avg(e.sal) as avgsal
from
	emp e
group by
	e.deptno)t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal;
+--------+-------------+-------+
| deptno | avgsal      | grade |
+--------+-------------+-------+
|     20 | 2175.000000 |     4 |
|     30 | 1566.666667 |     3 |
|     10 | 2916.666667 |     4 |
+--------+-------------+-------+

3.2取得部门中所有人的平均的薪水等级

select
	e.deptno,e.ename,s.grade
from
	emp e
join
	salgrade s
on
	e.sal between s.losal and s.hisal
order by
	e.deptno;
+--------+--------+-------+
| deptno | ename  | grade |
+--------+--------+-------+
|     10 | MILLER |     2 |
|     10 | CLARK  |     4 |
|     10 | KING   |     5 |
|     20 | SCOTT  |     4 |
|     20 | SIMITH |     1 |
|     20 | ADAMS  |     1 |
|     20 | JONES  |     4 |
|     20 | FORD   |     4 |
|     30 | BLAKE  |     4 |
|     30 | ALLEN  |     3 |
|     30 | TURNER |     3 |
|     30 | WARD   |     2 |
|     30 | JAMES  |     1 |
|     30 | MARTIN |     2 |
+--------+--------+-------+
select
	t.deptno,t.avgsal,s.grade
from
	 (select
	e.deptno,avg(e.sal) as avgsal
from
	emp e
group by
	e.deptno)t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal;
+--------+-------------+-------+
| deptno | avgsal      | grade |
+--------+-------------+-------+
|     20 | 2175.000000 |     4 |
|     30 | 1566.666667 |     3 |
|     10 | 2916.666667 |     4 |
+--------+-------------+-------+

4.不准用组函数(MAX),取得最高薪水(给出两种解决方案)

select sal from emp order by sal desc limit 1;

select sal from emp where sal not in(select
	distinct a.sal
from 
	emp a
join
	emp b
on
	a.sal

5.取得平均薪水最高的部门的部门编号
第一步:求出部门平均薪水

select
	e.deptno,avg(e.sal) as avgsal
from 
	emp e
group by
	e.deptno
having
	avgsal = (select max(t.avgsal) as maxAvgsal from (select
	e.deptno,avg(e.sal) as avgsal
from 
	emp e
group by
	e.deptno)t);
+--------+-------------+
| deptno | avgsal      |
+--------+-------------+
|     10 | 2916.666667 |
+--------+-------------+

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

select
	e.deptno,d.dname,avg(e.sal) as avgsal
from 
	emp e
join
	dept d
on 
	e.deptno = d.deptno
group by
	e.deptno,d.dname
having
	avgsal = (select max(t.avgsal) as maxAvgsal from (select
	e.deptno,avg(e.sal) as avgsal
from 
	emp e
group by
	e.deptno)t);
+--------+------------+-------------+
| deptno | dname      | avgsal      |
+--------+------------+-------------+
|     10 | ACCOUNTING | 2916.666667 |
+--------+------------+-------------+

第二种
select
	d.deptno,t.avgsal,d.dname
from 
	(select
	e.deptno,avg(e.sal) as avgsal
from 
	emp e
group by
	e.deptno
having
	avgsal = (select max(t.avgsal) as maxAvgsal from (select
	e.deptno,avg(e.sal) as avgsal
from 
	emp e
group by
	e.deptno)t))t
join
	dept d
on
	d.deptno = t.deptno;
+--------+-------------+------------+
| deptno | avgsal      | dname      |
+--------+-------------+------------+
|     10 | 2916.666667 | ACCOUNTING |
+--------+-------------+------------+
之前有一道题已经有了查询出最大值和部门编号把他当做一个t表然后和dept表查询就可以

7.求平均薪水的等级最低的部门的部门名称

第一步 部门的平均薪水
select
	e.deptno,avg(e.sal) as avgsal
from
	emp e
group by
	e.deptno;
+--------+-------------+
| deptno | avgsal      |
+--------+-------------+
|     20 | 2175.000000 |
|     30 | 1566.666667 |
|     10 | 2916.666667 |
+--------+-------------+

select
	t.deptno,s.grade,t.dname
from
	(select
	e.deptno,d.dname,avg(e.sal) as avgsal
from
	emp e
join
	dept d
on
	e.deptno = d.deptno
group by
	e.deptno)t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal;
+--------+-------+-------------+
| deptno | grade | dname       |
+--------+-------+-------------+
|     20 |     4 | RESEARCHING |
|     30 |     3 | SALES       |
|     10 |     4 | ACCOUNTING  |
+--------+-------+-------------+

select min(t.grade) as minGrade from (select
	t.deptno,s.grade,t.dname
from
	(select
	e.deptno,d.dname,avg(e.sal) as avgsal
from
	emp e
join
	dept d
on
	e.deptno = d.deptno
group by
	e.deptno)t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal)t;
+----------+
| minGrade |
+----------+
|        3 |
+----------+

select
	t.deptno,s.grade,t.dname
from
	(select
	e.deptno,d.dname,avg(e.sal) as avgsal
from
	emp e
join
	dept d
on
	e.deptno = d.deptno
group by
	e.deptno)t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal
where
	s.grade = (select min(t.grade) as minGrade from (select
	t.deptno,s.grade,t.dname
from
	(select
	e.deptno,d.dname,avg(e.sal) as avgsal
from
	emp e
join
	dept d
on
	e.deptno = d.deptno
group by
	e.deptno)t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal)t);
+--------+-------+-------+
| deptno | grade | dname |
+--------+-------+-------+
|     30 |     3 | SALES |
+--------+-------+-------+

8.取得比普通员工(员工代码没有在mgr上出现的)的最高薪水还要高的经理人姓名
第一步:找出普通员工(员工代码没有出现在mgr上的)
1.1先找出mgr有哪些人

select distinct mgr from emp;	
+------+
| mgr  |
+------+
| 7902 |
| 7698 |
| 7839 |
| 7566 |
| NULL |
| 7788 |
| 7782 |
+------+

select * from emp where empno not in(select distinct mgr from emp); 不对的
查询出来时空的not in不会自动忽略空值 有null参与的数学运算都为null
in会自动忽略空值
select max(sal) as maxsal from emp where empno  not in(select distinct mgr from emp where mgr is not null);
+---------+
| maxsal  |
+---------+
| 1600.00 |
+---------+

select ename from emp where sal>(select max(sal) as maxsal from emp where empno  not in(select distinct mgr from emp where mgr is not null));
+-------+
| ename |
+-------+
| JONES |
| BLAKE |
| CLARK |
| SCOTT |
| KING  |
| FORD  |
+-------+

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

select * from emp order by sal desc limit 0,5;
+-------+-------+-----------+------+------------+---------+------+--------+
| empno | ename | job       | mgr  | hiredate   | sal     | comm | deptno |
+-------+-------+-----------+------+------------+---------+------+--------+
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
|  7902 | FORD  | ANALYST   | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
|  7788 | SCOTT | ANALYST   | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
|  7566 | JONES | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
|  7698 | BLAKE | MANAGER   | 7839 | 1981-05-01 | 2850.00 | NULL |     30 |
+-------+-------+-----------+------+------------+---------+------+--------+

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

select * from emp order by sal desc limit 0,5;
+-------+-------+-----------+------+------------+---------+------+--------+
| empno | ename | job       | mgr  | hiredate   | sal     | comm | deptno |
+-------+-------+-----------+------+------------+---------+------+--------+
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
|  7902 | FORD  | ANALYST   | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
|  7788 | SCOTT | ANALYST   | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
|  7566 | JONES | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
|  7698 | BLAKE | MANAGER   | 7839 | 1981-05-01 | 2850.00 | NULL |     30 |
+-------+-------+-----------+------+------------+---------+------+--------+

11.取得最后入职的5名员工

select * from emp order by hiredate desc limit 5;
+-------+--------+---------+------+------------+---------+------+--------+
| empno | ename  | job     | mgr  | hiredate   | sal     | comm | deptno |
+-------+--------+---------+------+------------+---------+------+--------+
|  7876 | ADAMS  | CLERK   | 7788 | 1987-05-23 | 1100.00 | NULL |     20 |
|  7788 | SCOTT  | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
|  7934 | MILLER | CLERK   | 7782 | 1982-01-23 | 1300.00 | NULL |     10 |
|  7900 | JAMES  | CLERK   | 7698 | 1981-12-03 |  950.00 | NULL |     30 |
|  7902 | FORD   | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
+-------+--------+---------+------+------------+---------+------+--------+

12.取得每个薪水等级有多少员工
第一步查询出每个员工的薪水等级

select
	e.ename,s.grade
from
	emp e
join
	salgrade s
on
	e.sal between s.losal and s.hisal
order by
	s.grade;
+--------+-------+
| ename  | grade |
+--------+-------+
| SIMITH |     1 |
| ADAMS  |     1 |
| JAMES  |     1 |
| WARD   |     2 |
| MARTIN |     2 |
| MILLER |     2 |
| ALLEN  |     3 |
| TURNER |     3 |
| CLARK  |     4 |
| SCOTT  |     4 |
| JONES  |     4 |
| FORD   |     4 |
| BLAKE  |     4 |
| KING   |     5 |
+--------+-------+

select
	t.grade,count(t.ename) as totalEmp
from
	(select
	e.ename,s.grade
from
	emp e
join
	salgrade s
on
	e.sal between s.losal and s.hisal
order by
	s.grade)t
group by
	t.grade;
+-------+----------+
| grade | totalEmp |
+-------+----------+
|     1 |        3 |
|     3 |        2 |
|     2 |        3 |
|     4 |        5 |
|     5 |        1 |
+-------+----------+

14.列出所有员工及领导的名字

select
	e.ename,
	b.ename as leadername
from
	emp e
left join
	emp b
on
	e.mgr = b.empno;
+--------+------------+
| ename  | leadername |
+--------+------------+
| SIMITH | FORD       |
| ALLEN  | BLAKE      |
| WARD   | BLAKE      |
| JONES  | KING       |
| MARTIN | BLAKE      |
| BLAKE  | KING       |
| CLARK  | KING       |
| SCOTT  | JONES      |
| KING   | NULL       |
| TURNER | BLAKE      |
| ADAMS  | SCOTT      |
| JAMES  | BLAKE      |
| FORD   | JONES      |
| MILLER | CLARK      |
+--------+------------+
外连接查询的结果条数>= 内连接查询的结果条数	

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

select
	d.dname,
	e.empno,
	e.ename
from
	emp e
join
	emp b
on
	e.mgr = b.empno
join
	dept d
on
	e.deptno = d.deptno
where
	e.hiredate

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

select
	d.dname,
	e.*
from
	emp e
right join
	dept d
on
	e.deptno = d.deptno;
+-------------+-------+--------+-----------+------+------------+---------+---------+--------+
| dname       | empno | ename  | job       | mgr  | hiredate   | sal     | comm    | deptno |
+-------------+-------+--------+-----------+------+------------+---------+---------+--------+
| RESEARCHING |  7369 | SIMITH | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
| SALES       |  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
| SALES       |  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
| RESEARCHING |  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
| SALES       |  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
| SALES       |  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
| ACCOUNTING  |  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
| RESEARCHING |  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
| ACCOUNTING  |  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
| SALES       |  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    NULL |     30 |
| RESEARCHING |  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
| SALES       |  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
| RESEARCHING |  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
| ACCOUNTING  |  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
| OPERATIONS  |  NULL | NULL   | NULL      | NULL | NULL       |    NULL |    NULL |   NULL |
+-------------+-------+--------+-----------+------+------------+---------+---------+--------+

17.列出至少有5个员工的所有部门
第一步先求出每个部门的员工数量

select
		e.deptno,count(e.ename) as totalEmp
from
	emp e
group by
	e.deptno
having
	totalEmp>=5;

你可能感兴趣的:(34道经典SQL试题(上))