select
e.ename, t.max_sal sal, t.deptno
from
emp e
right join
(select deptno,max(p.sal) max_sal from emp p group by deptno) t
on
e.sal = t.max_sal
// error 少了个deptno相同条件
and
e.deptno = t.deptno;
+-------+---------+--------+
| ename | sal | deptno |
+-------+---------+--------+
| FORD | 3000.00 | 20 |
| SCOTT | 3000.00 | 20 |
| BLAKE | 2850.00 | 30 |
| KING | 5000.00 | 10 |
+-------+---------+--------+
4 rows in set (0.00 sec)
2.找出哪些人的薪资在部门的平均薪资之上
(利用了包含在where条件中的子查询)
select
ename,sal
from
emp
where
sal > (select avg(sal) from emp)
order by
sal desc;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
+-------+---------+
// error
这题理解有问题:找出那些人的薪资在其对应部门的平均薪资之上?
select
t.x, e.ename, e.sal
from
emp e
join
(select deptno,avg(sal) avg_sal from emp group by deptno) t
on
e.deptno = t.deptno
and
e.sal > t.avg_sal;
select
e.deptno, avg(s.grade)
from
emp e
left join
salgrade s
on
e.sal between s.losal and s.hisal
group by
e.deptno
order by
e.deptno;
+--------+-----------+
| deptno | avg_garde |
+--------+-----------+
| 10 | 3.6667 |
| 20 | 2.8000 |
| 30 | 2.5000 |
+--------+-----------+
解法1:
select
sal
from
emp
order by
sal desc
limit 1;
+---------+
| sal |
+---------+
| 5000.00 |
+---------+
// error
select
sal
from
emp
where
sal not in (
select distinct a.sal
from
emp a
join
emp b
on
a.sal < b.sal // 过滤出非最高薪资集合
) // 这手not in 集合是我没想到的 我还想怎么转换成逗号分隔的字符串再使用
5.找出平均薪水最高的部门的部门编号 多解法
(同理上面,以deptno分组后,以平均薪资排倒序,取第一个)
解法1:
select
deptno
from
emp
group by
deptno
order by
avg(sal) desc
limit 1;
+--------+
| deptno |
+--------+
| 10 |
+--------+
解法1:
select
d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno
group by e.deptno
order by
avg(e.sal) desc
limit 1;
+------------+
| dname |
+------------+
| ACCOUNTING |
+------------+
1 row in set (0.00 sec)
解法2:
select
dname
from
dept
where deptno = (select
deptno
from
emp
group by
deptno
order by
avg(sal) desc
limit 1;)
+------------+
| dname |
+------------+
| ACCOUNTING |
+------------+
1 row in set (0.01 sec)
select
d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno
group by
e.deptno
order by
avg(e.sal)
limit 1;
+-------+
| dname |
+-------+
| SALES |
+-------+
1 row in set (0.00 sec)
// error 特么的 又是审题失败
select
t.*, s.grade
from
(select
d.dname,avg(sal) avg_sal
from
emp e
join
dept d
on
e.deptno = d.deptno
group by
d.dname
)
join
salgrade s
on
t.avg_sal bewteen s.losal and s.hisal
where
s.grade = (
select grade from salgrade where (
select avg(sal) avg_sal
from
emp
group by
deptno
order by
avg_sal limit 1
) between losal and hisal
)
8.找出比普通员工(员工编码没有在mgr字段上出现的即为普通员工)的最高薪资还要高的领导人名称
(此题没做出来,原因是没搞懂in or not in语法,一直以为后面只能跟逗号分隔的字符串,结果in or not in后面跟的是集合,不知道是不是我把oracle用法搞混了)
select
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;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
5 rows in set (0.00 sec)
10.找出薪资最高得第六到第十名员工
select
ename,sal
from
emp
order by
sal desc
limit
5,5 // (5,5] 从第五位起不包括,长度5
+--------+---------+
| ename | sal |
+--------+---------+
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| WARD | 1250.00 |
+--------+---------+
5 rows in set (0.00 sec)
11.找出最后入职的5名员工
select
ename, hiredate
from
emp
order by
hiredate desc
limit 5;
+--------+------------+
| ename | hiredate |
+--------+------------+
| ADAMS | 1987-05-23 |
| SCOTT | 1987-04-19 |
| MILLER | 1982-01-23 |
| JAMES | 1981-12-03 |
| FORD | 1981-12-03 |
+--------+------------+
5 rows in set (0.00 sec)
12.找出每个薪资等级有多少名员工
select
s.grade, count(1)
from
emp e
left join
salgrade s
on
e.sal between s.losal and s.hisal
group by
s.grade;
+-------+----------+
| grade | count(1) |
+-------+----------+
| 1 | 3 |
| 3 | 2 |
| 2 | 3 |
| 4 | 5 |
| 5 | 1 |
+-------+----------+
5 rows in set (0.00 sec)
14.找出所有员工及领导的姓名
select
e.ename, ifnull(p.ename,'没有上级')
from
emp e
left join
emp p
on
e.mgr = p.empno;
+--------+--------+
| ename | name |
+--------+--------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | ?????? |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+--------+--------+
14 rows in set, 1 warning (0.00 sec)
15.找出受雇日期早于其直接上级的 所有员工的编号、姓名、部门名称
select
e.empno, e.ename, d.dname
from
emp e
join
emp p
on
e.mgr = p.empno and e.hiredate < p.hiredata
join
dept d
on
e.deptno = d.deptno;
+-------+-------+------------+
| empno | ename | dname |
+-------+-------+------------+
| 7369 | SMITH | RESEARCH |
| 7499 | ALLEN | SALES |
| 7521 | WARD | SALES |
| 7566 | JONES | RESEARCH |
| 7698 | BLAKE | SALES |
| 7782 | CLARK | ACCOUNTING |
+-------+-------+------------+
6 rows in set (0.00 sec)
select
d.dname,count(1)
from
emp e
join
dept d
on
e.deptno = d.deptno
group by
d.dname
having
count(1) >= 5;
+----------+----------+
| dname | count(1) |
+----------+----------+
| RESEARCH | 5 |
| SALES | 6 |
+----------+----------+
select
e.ename, d.dname,
(select count(1) from emp where deptno = d.deptno) cc
from
emp e
join
dept d
on
e.deptno = d.deptno
where
e.job = 'clerk'
+--------+------------+------+
| ename | dname | cc |
+--------+------------+------+
| SMITH | RESEARCH | 5 |
| ADAMS | RESEARCH | 5 |
| JAMES | SALES | 6 |
| MILLER | ACCOUNTING | 3 |
+--------+------------+------+
4 rows in set (0.00 sec)
select
e.job, count(1)
from
emp e
group by e.job
having
min(e.sal) > 1500;
+-----------+----------+
| job | count(1) |
+-----------+----------+
| MANAGER | 3 |
| ANALYST | 2 |
| PRESIDENT | 1 |
+-----------+----------+
3 rows in set (0.00 sec)
21.找出在部门’sales’(销售部)工作的员工的姓名,假定不知道销售部的部门编号
select
e.ename
from
emp e
join
dept d
on
e.deptno = d.deptno
and
d.dname = 'sales';
+--------+
| ename |
+--------+
| ALLEN |
| WARD |
| MARTIN |
| BLAKE |
| TURNER |
| JAMES |
+--------+
6 rows in set (0.00 sec)
select
e.ename, d.dname, p.ename, s.grade
from
emp e
left join
dept d
on
e.deptno = d.deptno
left join
emp p
on
e.mgr = p.empno
left join
salgrade s
on
e.sal between s.losal and s.hisal
where
e.sal > (select avg(sal) from emp);
+-------+------------+-------+-------+
| ename | dname | ename | grade |
+-------+------------+-------+-------+
| JONES | RESEARCH | KING | 4 |
| BLAKE | SALES | KING | 4 |
| CLARK | ACCOUNTING | KING | 4 |
| SCOTT | RESEARCH | JONES | 4 |
| KING | ACCOUNTING | NULL | 5 |
| FORD | RESEARCH | JONES | 4 |
+-------+------------+-------+-------+
6 rows in set (0.00 sec)
select
e.ename, d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno
where
e.job = (select job from emp where ename = 'scott')
and
e.ename <> 'scott';
+-------+----------+
| ename | dname |
+-------+----------+
| FORD | RESEARCH |
+-------+----------+
1 row in set (0.00 sec)
select
*
from
(select sal from emp where deptno <> 30) a
join
(select sal from emp where deptno = 30) b
on
a.sal = b.sal;
Empty set (0.00 sec)
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);
+-------+---------+------------+
| ename | sal | dname |
+-------+---------+------------+
| JONES | 2975.00 | RESEARCH |
| SCOTT | 3000.00 | RESEARCH |
| KING | 5000.00 | ACCOUNTING |
| FORD | 3000.00 | RESEARCH |
+-------+---------+------------+
4 rows in set (0.00 sec)
select
e.*
from
(select job,min(sal) min_sal from emp group by job) t
left join
emp e
on
t.job = e.job
and
t.min_sal = e.sal;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.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 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
7 rows in set (0.00 sec)
30.找出各个部门的manager(领导)的最低薪资
select
deptno,min(sal)
from
emp
where
job = 'manager'
group by
deptno;
+--------+----------+
| deptno | min(sal) |
+--------+----------+
| 20 | 2975.00 |
| 30 | 2850.00 |
| 10 | 2450.00 |
+--------+----------+
3 rows in set (0.00 sec)
31.找出所有员工的年工资,按年薪从低到高排序
select
ename, 12*sal year_sal
from
emp
order by
year_sal;
+--------+----------+
| ename | yearSal |
+--------+----------+
| SMITH | 9600.00 |
| JAMES | 11400.00 |
| ADAMS | 13200.00 |
| WARD | 15000.00 |
| MARTIN | 15000.00 |
| MILLER | 15600.00 |
| TURNER | 18000.00 |
| ALLEN | 19200.00 |
| CLARK | 29400.00 |
| BLAKE | 34200.00 |
| JONES | 35700.00 |
| SCOTT | 36000.00 |
| FORD | 36000.00 |
| KING | 60000.00 |
+--------+----------+
14 rows in set (0.00 sec)
32.找出员工领导的薪资超过3000的员工名称与领导名称
select
e.ename, p.ename
from
emp e
join
emp p
on
e.mgr = p.empno
where
p.sal > 3000;
+-------+-------+
| ename | ename |
+-------+-------+
| JONES | KING |
| BLAKE | KING |
| CLARK | KING |
+-------+-------+
3 rows in set (0.00 sec)
33.找出部门名字中带’s’字符的部门员工的工资合计、部门人数
select
d.dname,
ifnull(sum(e.sal),'') '工资合计',
(select count(1) from emp where deptno = d.deptno) '员工人数'
from
emp e
right join
dept d
where
d.dname like '%s%'
group by d.deptno;
+------------+----------+----------+
| dname | 工资合计 | 员工人数 |
+------------+----------+----------+
| RESEARCH | 10875.00 | 5 |
| SALES | 9400.00 | 6 |
| OPERATIONS | | 0 |
+------------+----------+----------+
3 rows in set (0.00 sec)
34.给任职日期超过30年的员工加薪10%
(同理使用上面的timestampdiff函数)
update
emp e
set e.sal = e.sal * 1.1
where
2022 - subtr(e.hiredate,1,4) > 30;
select ename,sal from emp;
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 880.00 |
| ALLEN | 1760.00 |
| WARD | 1375.00 |
| JONES | 3272.50 |
| MARTIN | 1375.00 |
| BLAKE | 3135.00 |
| CLARK | 2695.00 |
| SCOTT | 3300.00 |
| KING | 5500.00 |
| TURNER | 1650.00 |
| ADAMS | 1210.00 |
| JAMES | 1045.00 |
| FORD | 3300.00 |
| MILLER | 1430.00 |
+--------+---------+
14 rows in set (0.00 sec)