员工表建表语句
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (
`EMPNO` int(4) NOT NULL COMMENT '员工编号',
`ENAME` varchar(10) DEFAULT NULL COMMENT '员工姓名',
`JOB` varchar(9) DEFAULT NULL COMMENT '工作岗位',
`MGR` int(4) DEFAULT NULL COMMENT '上级经理',
`HIREDATE` date DEFAULT NULL,
`SAL` double(7,2) DEFAULT NULL,
`COMM` double(7,2) DEFAULT NULL,
`DEPTNO` int(2) DEFAULT NULL,
PRIMARY KEY (`EMPNO`),
KEY `DEPTNO` (`DEPTNO`),
KEY `SAL` (`SAL`),
CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`DEPTNO`) REFERENCES `dept` (`DEPTNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='员工编号';
员工表数据
INSERT INTO `emp` VALUES ('7369', 'SMITH', 'CLERK', '7902', '1980-12-17', '800.00', null, '20');
INSERT INTO `emp` VALUES ('7499', 'ALLEN', 'SALESMAN', '7698', '1981-02-20', '1600.00', '300.00', '30');
INSERT INTO `emp` VALUES ('7521', 'WARD', 'SALESMAN', '7698', '1981-02-22', '1250.00', '500.00', '30');
INSERT INTO `emp` VALUES ('7566', 'JONES', 'MANAGER', '7839', '1981-04-02', '2975.00', null, '20');
INSERT INTO `emp` VALUES ('7654', 'MARTIN', 'SALESMAN', '7698', '1981-09-28', '1250.00', '1400.00', '30');
INSERT INTO `emp` VALUES ('7698', 'BLAKE', 'MANAGER', '7839', '1981-05-01', '2850.00', null, '30');
INSERT INTO `emp` VALUES ('7782', 'CLARK', 'MANAGER', '7839', '1981-06-09', '2450.00', null, '10');
INSERT INTO `emp` VALUES ('7788', 'SCOTT', 'ANALYST', '7566', '1987-04-19', '3000.00', null, '20');
INSERT INTO `emp` VALUES ('7839', 'KING', 'PRESIDENT', null, '1981-11-17', '5000.00', null, '10');
INSERT INTO `emp` VALUES ('7844', 'TURNER', 'SALESMAN', '7698', '1981-09-08', '1500.00', '0.00', '30');
INSERT INTO `emp` VALUES ('7876', 'ADAMS', 'CLERK', '7788', '1981-05-23', '1100.00', null, '20');
INSERT INTO `emp` VALUES ('7900', 'JAMES', 'CLERK', '7698', '1981-12-03', '950.00', null, '30');
INSERT INTO `emp` VALUES ('7902', 'FORD', 'ANALYST', '7566', '1981-12-03', '3000.00', null, '20');
INSERT INTO `emp` VALUES ('7934', 'MILLER', 'CLERK', '7782', '1982-01-23', '1300.00', null, '10');
部门表建表语句
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
`DEPTNO` int(2) NOT NULL COMMENT '部门编号',
`DNAME` varchar(14) DEFAULT NULL COMMENT '部门名称',
`LOC` varchar(13) DEFAULT NULL COMMENT '位置',
PRIMARY KEY (`DEPTNO`)
) ENGINE=InnoDB;
部门表数据
INSERT INTO `dept` VALUES ('10', 'ACCOUNTING', 'NEW YORK');
INSERT INTO `dept` VALUES ('20', 'RESEARCH', 'DALLAS');
INSERT INTO `dept` VALUES ('30', 'SALES', 'CHICAGO');
INSERT INTO `dept` VALUES ('40', 'OPERATIONS', 'BOSTON');
薪水等级表建表语句
DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade` (
`GRADE` int(11) DEFAULT NULL,
`LOSAL` int(11) DEFAULT NULL,
`HISAL` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
薪水表数据
INSERT INTO `salgrade` VALUES ('1', '700', '1200');
INSERT INTO `salgrade` VALUES ('2', '1201', '1400');
INSERT INTO `salgrade` VALUES ('3', '1401', '2000');
INSERT INTO `salgrade` VALUES ('4', '2001', '3000');
INSERT INTO `salgrade` VALUES ('5', '3001', '9999');
表结构如下;
a.查询每个部门最高薪水
SELECT
e.deptno,
max(e.sal) AS maxSal
FROM
emp e
GROUP BY
e.deptno;
b.将以上查询结果当成一个临时表 t(deptno,maxSal)---此语句不能运行属于分步逻辑语句
select e.deptno,e.ename,t.maxSal ,e.sal from t join emp e on t.deptno=e.deptno where t.maxSal=e.sal;
c.把a中查询语句带入b中的t
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;
最终答案:
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;
运行结果:
a.查询每个部门的平均薪水
#求出每个部门的平均薪水
SELECT
e.deptno,
max(e.sal)
FROM
emp e
GROUP BY
e.deptno;
b.将以上查询结果当成一个临时表 t(deptno,maxSal)
select t.deptno ,e.ename from t join emp e on e.deptno=t.deptno where e.sal >t.avgSal;
c.把a中j结果代入 临时表t
#将以上查询结果当成一个临时表 t(deptno,maxSal)把a中j结果代入 临时表t
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;
最终答案:
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;
运行结果:
此句话有两种含义
2.3.1)求出部门中(所有人)平均薪水的薪水等级
a.求出部门的平均薪水
#求出部门的平均薪水
SELECT
e.deptno,
avg(e.sal) AS avgSal
FROM
emp e
GROUP BY
e.deptno;
b.将以上查询结果当成一个临时表 t(deptno,avgSal)
select t.deptno,t.avgSal,s.grade from t join salgrade s on t.avgSal between s.losal and s.hisal order by
t.deptno;
c.把a中的结果代入b中临时表t
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
ORDER BY
t.deptno;
最终答案:
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
ORDER BY
t.deptno;
运行结果:
2.3.2)求出部门中(所有人)平均的薪水等级
a)求出每个人的薪水等级
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;
b) 将a查询结果当成一个临时表 t(deptno,ename,grade)
SELECT
t.deptno,
avg(t.grade)
FROM
(
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
) t
GROUP BY
t.deptno;
最后结果:
SELECT
t.deptno,
avg(t.grade)
FROM
(
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
) t
GROUP BY
t.deptno;
运行结果:
2.4.1 使用limit 结合order by 排序(降序),取第一个
SELECT
sal
FROM
emp
ORDER BY
sal DESC
LIMIT 1;
最后答案:
SELECT
sal
FROM
emp
ORDER BY
sal DESC
LIMIT 1;
运行结果:
2.4.2 采用自关联,通过自连接后a表的工资小于b表的薪水记录,并用distinc 去除重复,最后取不在范围内的结果
a.首先查出通过自连接后a表的工资小于b表的薪水记录,并用distinc 去除重复
#首先查出通过自连接后a表的工资小于b表的工资记录,并用distinc 去除重复
SELECT DISTINCT
(a.sal)
FROM
emp a
JOIN emp b ON a.sal < b.sal;
b.最后取不在a范围内的薪水结果
#查询出不在a结果薪水范围内的薪水
SELECT
e.sal
FROM
emp e
WHERE
e.sal NOT IN (
SELECT DISTINCT
(a.sal)
FROM
emp a
JOIN emp b ON a.sal < b.sal
);
最后答案:
#================================================
SELECT
e.sal
FROM
emp e
WHERE
e.sal NOT IN (
SELECT DISTINCT
(a.sal)
FROM
emp a
JOIN emp b ON a.sal < b.sal
);
运行结果:
a.查询各个部门的平均薪水
#==========================================================
SELECT
e.deptno,
avg(e.sal) AS avgSal
FROM
emp e
GROUP BY
e.deptno;
b.将a查询结果当做临时表 t(deptno,avgSal )查询各个部门平均薪水的最大值
select max(t.avgSal) as maxAvgSal from t;
代入a
#==========================================
SELECT
max(t.avgSal) AS maxAvgSal
FROM
(
SELECT
e.deptno,
avg(e.sal) AS avgSal
FROM
emp e
GROUP BY
e.deptno
) t;
c.通过分组过滤出最大平均薪水的部门编号
#====================================
SELECT
e.deptno,
avg(e.sal) 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
);
最后答案:
#====================================
SELECT
e.deptno,
avg(e.sal) 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
);
运行结果:
a.取得平均薪水最高的部门的部门编号即2.5题的答案
SELECT
e.deptno,
avg(e.sal) 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
);
b.关联部门表一起查询
SELECT
d.deptno,
d.dname,
avg(e.sal) avgSal
FROM
emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY
d.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
);
最后答案:
SELECT
d.deptno,
d.dname,
avg(e.sal) avgSal
FROM
emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY
d.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
);
运行结果:
a,求各个部门平均薪水
SELECT
d.deptno,
d.dname,
avg(sal) AS avgSal
FROM
emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY
d.deptno,
d.dname;
+--------+------------+-------------+
| deptno | dname | avgSal |
+--------+------------+-------------+
| 10 | ACCOUNTING | 2916.666667 |
| 20 | RESEARCH | 2175.000000 |
| 30 | SALES | 1566.666667 |
+--------+------------+-------------+
b.将a结果当做一个临时表t(deptno,d,dnam,avgsal) 与等级表关联查询
SELECT
s.grade,
t.deptno,
t.dname
FROM
(
SELECT
d.deptno,
d.dname,
avg(sal) AS avgSal
FROM
emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY
d.deptno,
d.dname
) t
JOIN salgrade s ON t.avgsal BETWEEN s.losal
AND s.hisal;
+-------+--------+------------+c,将b中结果当做一张临时表tem(grade,depeno,dname),查询最低等级
select min(tem.grade) as minGrade,tem.depeno,tem.dname from tem;
SELECT
min(grade) AS minGrade
FROM
(
SELECT
s.grade,
t.deptno,
t.dname
FROM
(
SELECT
d.deptno,
d.dname,
avg(sal) AS avgSal
FROM
emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY
d.deptno,
d.dname
) t
JOIN salgrade s ON t.avgsal BETWEEN s.losal
AND s.hisal
) tem;
+----------+
| minGrade |
+----------+
| 3 |
+----------+
d.把b的结果用c结果作为条件过滤
select s.grade,t.deptno,t.dname from (select d.deptno,d.dname,avg(sal) as avgSal from emp e join dept d on e.deptno =d.deptno group by d.deptno,d.dname)t join salgrade s on t.avgsal between s.losal and s.hisal where s.grade=3;
SELECT
s.grade,
t.deptno,
t.dname
FROM
(
SELECT
d.deptno,
d.dname,
avg(sal) AS avgSal
FROM
emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY
d.deptno,
d.dname
) t
JOIN salgrade s ON t.avgsal BETWEEN s.losal
AND s.hisal
WHERE
s.grade = (
SELECT
min(grade) AS minGrade
FROM
(
SELECT
s.grade,
t.deptno,
t.dname
FROM
(
SELECT
d.deptno,
d.dname,
avg(sal) AS avgSal
FROM
emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY
d.deptno,
d.dname
) t
JOIN salgrade s ON t.avgsal BETWEEN s.losal
AND s.hisal
) tem
);
+-------+--------+-------++-------+--------+-------+
最后答案:
SELECT
s.grade,
t.deptno,
t.dname
FROM
(
SELECT
d.deptno,
d.dname,
avg(sal) AS avgSal
FROM
emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY
d.deptno,
d.dname
) t
JOIN salgrade s ON t.avgsal BETWEEN s.losal
AND s.hisal
WHERE
s.grade = (
SELECT
min(grade) AS minGrade
FROM
(
SELECT
s.grade,
t.deptno,
t.dname
FROM
(
SELECT
d.deptno,
d.dname,
avg(sal) AS avgSal
FROM
emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY
d.deptno,
d.dname
) t
JOIN salgrade s ON t.avgsal BETWEEN s.losal
AND s.hisal
) tem
);
运行结果:
a 查询出普通员工(员工代码没有出现在mgr上出现的)
:a1) 查询出mgr 有哪些人
select e.mgr from emp e;
| mgr |
+------+
| 7902 |
| 7698 |
| 7698 |
| 7839 |
| 7698 |
| 7839 |
| 7839 |
| 7566 |
| NULL |
| 7698 |
| 7788 |
| 7698 |
| 7566 |
| 7782 |
+------+
| 7782 |
+------+
mgr 有重复,所以要去除重复。
select distinct e.mgr from emp e;
+------+mgr 有空值,所以要去除空值。
SELECT DISTINCT
e.mgr
FROM
emp e
WHERE
e.mgr IS NOT NULL;
+------+a2)查询不是mgr的普通员工所有信息
SELECT
*
FROM
emp e
WHERE
e.empno NOT IN (
SELECT DISTINCT
e.mgr
FROM
emp e
WHERE
e.mgr IS NOT NULL
);
+-------+--------+----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1981-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+----------+------+------------+---------+---------+--------+
b.查询出普通员工的最高薪水
SELECT
max(e.sal)
FROM
emp e
WHERE
e.empno NOT IN (
SELECT DISTINCT
e.mgr
FROM
emp e
WHERE
e.mgr IS NOT NULL
);
+----------+
| max(sal) |
+----------+
| 1600.00 |
+----------+
c 查询比普通员工工资还要高的员工---即经理
SELECT
e.ename,e.sal
FROM
emp e
WHERE
e.sal > (
SELECT
max(sal)
FROM
emp e
WHERE
e.empno NOT IN (
SELECT DISTINCT
e.mgr
FROM
emp e
WHERE
e.mgr IS NOT NULL
)
)
+-------+---------++-------+---------+
最后答案:
SELECT
e.ename,e.sal
FROM
emp e
WHERE
e.sal > (
SELECT
max(sal)
FROM
emp e
WHERE
e.empno NOT IN (
SELECT DISTINCT
e.mgr
FROM
emp e
WHERE
e.mgr IS NOT NULL
)
);
运行结果:
最终答案:
SELECT
*
FROM
emp e
ORDER BY
sal DESC
LIMIT 0,
5;
运行结果:
最终答案:
SELECT
*
FROM
emp e
ORDER BY
sal desc
LIMIT 5,
5;
limit 一个参数表示从第几开始,第二个参数表示去的长度
运行结果
最终答案:
#---第一种写法
SELECT
*
FROM
emp e
ORDER BY
HIREDATE desc
LIMIT 0,
5;
#---第二种写法
SELECT
*
FROM
emp e
ORDER BY
HIREDATE desc
LIMIT
5;
运行结果:
最终答案:
SELECT
s.GRADE,
COUNT(e.ename)
FROM
emp e
JOIN salgrade s ON e.sal BETWEEN s.LOSAL
AND s.HISAL
GROUP BY
s.GRADE;
运行结果: