文章目录
- 一、建表语句
- 二、插入测试数据
- 三、练习题
- 1、取得每个部门最高薪水的人员名称
- 2、哪些人的薪水在部门的平均薪水之上(△)
- 3、取得部门中(所有人的)平均的薪水等级
- 4、不准用组函数(max),取得最高薪水(至少两种解决方案)
- 5、取得平均薪水最高的部门的部门编号(至少两种解决方案)
- 6、取得平均薪水最高的部门的部门名称
- 7、求平均薪水的等级最低的部门的部门名称(△)
- 8、取得比普通员工(员工代码没有在mgr字段上出现的)的最高薪水还要高的领导人姓名(△)
- 9、取得薪水最高的前五名员工
- 10、取得薪水最高的第六到第十名员工
- 11、取得最后入职的 5 名员工日期
- 12、取得每个薪水等级有多少员工
- 13、面试题略过
- 14、列出所有员工及领导的姓名
- 15、列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称
- 16、 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门
- 17、列出至少有 5 个员工的所有部门
- 18、列出薪金比"SMITH" 多的所有员工信息
- 19、 列出所有"CLERK"( 办事员) 的姓名及其部门名称, 部门的人数
- 20、列出最低薪金大于 1500 的各种工作及从事此工作的全部雇员人数,按照工作岗位分组求最小值(△)
- 21、列出在部门"SALES"< 销售部> 工作的员工的姓名,假定不知道销售部的部门编号
- 22、列出薪金高于公司平均薪金的所有员工, 所在部门,上级领导,雇员的工资等级
- 23、 列出与"SCOTT" 从事相同工作的所有员工及部门名称
- 24、列出薪金等于部门 30 中员工的薪金的其他员工的姓名和薪金
- 25、列出薪金高于在部门 30 工作的所有员工的薪金的员工姓名和薪金、部门名称
- 26、列出在每个部门工作的员工数量, 平均工资和平均服务期限(△)
- 27、列出所有员工的姓名、部门名称和工资
- 28、列出所有部门的详细信息和人数
- 29、列出各种工作的最低工资及从事此工作的雇员姓名
- 30、列出各个部门的MANAGER(领导)的最低薪金
- 31、列出所有员工的年工资, 按年薪从低到高排序
- 32、求出员工领导的薪水超过3000的员工名称与领导
- 33、求出部门名称中, 带’S’字符的部门员工的工资合计、部门人数
- 34、给任职日期超过 30 年的员工加薪 10%
- 四、视频链接
一、建表语句
-- 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