HAVING子句
概念:
HAVING子句查询,就是对分组统计函数统计出的结果进行果过滤的子句。
HAVING子句使用的基本语法:
查询出平均工资高于2000的职位的名称和平均工资
SELECT job ,AVG(sal)
FROM emp
GROUP BY job
HAVING AVG(sal);
查询出非销售人员的工作名称以及从事同一工作的雇员的月工资总和,并且要求从事一工作的雇员工资合计大于五千,输出结果按照雇员的薪资之和升序排列
SELECT job,SUM(sal) 工资总和
FROM emp
WHERE job<>'SALESMAN'
GROUP BY job
HAVING SUM(sal)>5000
ORDER BY 工资总和 ASC;
查询出薪资低于平均工资的雇员信息
SELECT *
FROM emp
WHEER sal<(
SELECT AVG(sal)
FROM emp
);
说明WHERE子句和HAVING子句的区别
WHERE子句在GROUP BY 子句之前执行,不能在WHERE字句中使用统计函数。
HAVING子句在GROUP BY 子句之后执行,可以在HAVING字句中对统计函数进行过滤。
WHERE子查询
概念:
子查询就是将一个查询的结果作为另外一个查询(主查询)的数据来源或者判断条件的查询
查询出低于平均工资的雇员信息
SELECT *
FROM emp
WHERE sal<(
SELECT AVG(sal)
FROM emp);
查询出公司最早入职的雇员信息
SELECT *
FROM emp
WHERE hiredate=(SELECT MIN(hiredate) FROM emp);
查询出与scott从事同一工作,并且工资相同的雇员的信息
SELECT *
FROM emp
WHERE (job,sal)=(SELECT job,sal FROM emp WHERE ename='SCOTT')
AND ename <> 'SCOTT';
查询出与经理职位工资相同的员工信息(返回结果是多行单列的结果集)
SELECT *
FROM emp
WHERE sal IN (SELECT sal FROM emp WHERE job='MANAGER')
AND job<>'MANAGER';
查询出薪资比经理职位中最低薪资高的员工信息
SELECT *
FROM emp
WHERE sal>(SELECT MIN(sal) FROM emp WHERE job='MANAGER');
方式二:使用any实现
SELECT *
FROM emp
WHERE sal> ANY(SELECT sal FROM emp WHERE job='MANAGER');
sal>any:表示的是sal大于子查询中的最小的一个值即可
查询出薪资比经理职位中最高薪资低的员工信息
SELECT *
FROM emp
WHERE sal<(SELECT MAX(sal) FROM emp WHERE job='MANAGER');
SELECT *
FROM emp
WHERE sal<ANY(SELECT sal FROM emp WHERE job='MANAGER');
sal>any:表示的是sal小于子查询中的最大的一个值即可
查询出比经理职位中最高工资高的员工的信息
SELECT *
FROM emp
WHERE sal>ALL(SELECT sal FROM emp WHERE job='MANAGER');
HAVING子查询
概念:
HAVING子句是对分组统计函数进行过滤的子句,也可以在HAVING子句中使用子查询,这就是HAVING子查询。
查询出平均薪资高于所有员工平均工资的职位的名称、以及职位的人数、这些高于平均工资的职位的平均工资
SELECT job,COUNT(*) 人数,AVG(sal)
FROM emp
GROUP BY job
HAVING AVG(sal)>(SELECT AVG(sal) FROM emp);
查询出平均薪资最高的职位名称和该职位的平均工资
SELECT job,AVG(sal)
FROM emp
GROUP BY job
HAVING AVG(sal)=(
SELECT MAX(AVG(sal))
FROM emp
GROUP BY job);
查询出薪资排名第三的雇员的信息(不考虑并列薪资)
SELECT *
FROM emp
WHERE sal=
SELECT MAX(sal)
FROM emp
WHERE sal<(
SELECT MAX(sal)
FROM emp
WHERE sal<(
SELECT MAX(sal)
FROM emp)));
FROM子查询
概念:
FROM子句的数据来源不仅仅可以是数据表,还可以是一个查询的结果(一般是多行多列类型的数据)
把一个查询的结果作为主查询的数据来源,这就是FROM子查询。
DEMO:查询出平均工资高于2000的职位名称以及该职位的平均工资
第一种方式:可以使用HAVING子句实现
SELECT job,AVG(sal)
FROM emp
GROUP BY job
HAVING AVG(sal)>2000;
第二种方式:使用FROM子查询实现
SELECT job,avgsal
FROM (
SELECT job,AVG(sal) avgsal
FROM emp
GROUP BY job) temp
WHERE temp.avgsal>2000;
DEMO:查询出有佣金的并且薪资高于佣金的雇员,该雇员的编号、姓名、佣金和薪资
SELECT e1.empno,e1.ename,e1.comm,e2.sal
FROM emp e1 ,emp e2
WHERE e1.comm IS NOT NULL AND e1.comm<e2.sal AND e1.empno=e2.empno;
总结:
- 1.FROM子查询的结果作为主查询的数据来源,子查询的结果相当于一张临时数据表。
- 2.规范的做法就需要为子查询定义别名。
- 3.如果要使用子查询的字段则应该使用“别名.字段名”的方式进行引用。
查询各岗位的最高薪水,最低薪水。要求只统计薪水>1000的
SELECT job,MAX(sal) 最高薪水,MIN(sal) 最低薪水
FROM emp
WHERE sal>1000
GROUP BY job;
查询各部门的平均薪水及部门编号,要求只列出平均薪水>2000
1.SELECT temp.deptno,avgsal
FROM (
SELECT deptno,AVG(sal) avgsal
FROM emp
GROUP BY deptno) temp
WHERE temp.avgsal>2000;
2.SELECT deptno,AVG(sal) avasal
FROM emp
GROUP BY deptno
HAVING AVG(sal)>2000;
3.SELECT DISTINCT e.deptno,t.avgsal
FROM emp e,(SELECT deptno,AVG(sal) avgsal FROM emp GROUP BY deptno) t
WHERE e.deptno=t.deptno AND t.avgsal>2000;
查询各部门的平均薪水及部门编号,要求只有员工姓名中包含“A”才参与统计,只列出平均薪水>1500的,按照平均薪水降序排列
SELECT deptno 编号,AVG(sal) 平均薪水
FROM emp
WHERE ename LIKE '%A%'
GROUP BY deptno
HAVING AVG(sal)>1500
ORDER BY AVG(sal) DESC;
查询最高薪水的员工信息
SELECT *
FROM emp
WHERE sal=(
SELECT MAX(sal)
FROM emp);
查询薪水大于该部门平均薪水的员工信息
SELECT *
FROM emp e,(SELECT deptno,AVG(sal) avgsal
FROM emp
GROUP BY deptno) temp
WHERE e.deptno=temp.deptno AND sal>temp.avgsal;
查询各部门最高薪水的员工信息
SELECT e.empno,e.ename,e.job,e.sal,e.comm,e.hiredate,t.deptno,最高薪水
FROM emp e ,(SELECT deptno,MAX(sal) 最高薪水 FROM emp GROUP BY deptno) t
WHERE e.deptno=t.deptno AND sal=t.最高薪水;
查询出薪资高于佣金的雇员的信息
SELECT e1.empno,e1.ename,e1.job,e1.sal,e1.comm,e1.hiredate
FROM emp e1 ,emp e2
WHERE e1.empno=e2.empno AND e1.comm IS NOT NULL AND e1.sal>e2.comm;