聚合函数
聚合函数:
max(计算的字段) 求最大值
min(计算的字段) 求最小值
avg(计算的字段) 求平均值
count(计算的字段) 求统计个数
sum(计算的字段) 求和
分组函数 GROUP BY
代码语法:
1 聚合函数,可以单独使用,直接放在 SELECT 后面可以直接查出结果
2 聚合函数,逻辑是进行汇总后的计算,计算结果返回一个值。
3 分组 GROUP BY 和 聚合函数一起使用的时候, 每个组会返回一个值。
4 聚合函数,如果要跟其他的字段一起查询出来,那么必须对其他的字段进行分组 [或者可以套个聚合函数]
5 GROUP BY ,是对查询的结果集进行分组,这样会改变结果集中的数据,分组以 后,SELECT 后面只能跟 被分组的字段 和 聚合函数。
6 只要在 SELECT 后面跟了任意一个聚合函数,那么其他字段必须是分组的字段。
7 表中不存在数据,不受聚合函数和 group BY 的语法约束。
SELECT E.deptno , MAX(E.SAL) , MIN(E.sal) , AVG(E.sal), COUNT(1) , SUM(E.sal)
FROM EMP E
GROUP BY E.deptno
ORDER BY E.deptno;
SELECT E.deptno ,1 ,'ABC'
FROM EMP E
GROUP BY E.deptno
– 查出平均工资高于 2000的部门的员工人数
SELECT DEPTNO 部门,COUNT(1) 人数 ,AVG(SAL) 平均工资
FROM EMP
GROUP BY DEPTNO
HAVING AVG(SAL) > 2000
AND DEPTNO != 10 ;
SQL语句执行顺序:
SELECT --5 要查询的字段/结果
FROM --1 要查询的表
WHERE -- 2 过滤条件【不能直接跟 聚合函数 做条件】
AND
GROUP BY --3 分组条件
HAVING -- 4 分组后的过滤条件
-- 【可以直接把聚合函数作为条件,但是非分组的字段和聚合函 数之外条件,不能放在后面过滤】
AND
ORDER BY -- 6
WHERE 和 HAVING 的相同点和不同点:
相同点:
都可以跟过滤条件 ,并且后面可以跟无限多个 AND
只要是需要过滤,第一个必须是 WHERE 或者 HAVING
不同点:
WHERE 后面可以跟除了聚合函数之外的所有条件。 不能直接跟聚合函数
WHERE 条件必须放在 group by 表达式之前。
WHERE 后面如果需要使用聚合函数作为条件,必须使用子查询。
HAVING 后面只能跟聚合函数和被分组的字段。
HAVING 条件必须放在 group by 表达式之后。
HAVING 可以直接把聚合函数当成条件直接过滤。
比如下面的例子:
– 查出平均工资高于 2000的部门的员工人数
SELECT SUM(COUNT(1))
FROM EMP
GROUP BY DEPTNO
HAVING AVG(SAL) > 2000;
SELECT COUNT(1)
FROM EMP
WHERE DEPTNO IN
(SELECT DEPTNO FROM EMP GROUP BY DEPTNO HAVING AVG(SAL) > 2000);
– 查询出工资高于 全公司平均工资 的员工的人数
SELECT count(1)
FROM EMP
WHERE SAL > (SELECT AVG(SAL) FROM EMP ) -- 公司的平均工资
– 查询出工资高于 员工所在部门平均工资 的员工的信息
1 查出员工 SMITH 所在部门的平均工资
SELECT AVG(SAL)
FROM EMP
WHERE DEPTNO = (SELECT DEPTNO FROM EMP WHERE ENAME = 'SMITH')
2 员工的工资 > 员工所在部门的平均工资
SELECT E.*
FROM EMP E
WHERE E.SAL > (SELECT AVG(SAL) FROM EMP WHERE DEPTNO = E.deptno )
ORDER BY DEPTNO ASC;
SELECT AVG(SAL)
FROM EMP
GROUP BY DEPTNO ;
– 查询出各部门平均工资,但是显示为下面的效果:
部门10 ,部门20 ,部门30
2900 2175 1566
SELECT
ROUND(AVG(DECODE(E.deptno,10 ,E.sal))) 部门10,
ROUND(AVG(DECODE(E.deptno,20 ,E.sal))) 部门20,
ROUND(AVG(DECODE(E.deptno,30 ,E.sal))) 部门30
FROM EMP E ;
SELECT
MAX(DECODE(DEPTNO ,10 ,AVGSAL)) 部门10,
MIN(DECODE(DEPTNO ,20 ,AVGSAL)) 部门20,
AVG(DECODE(DEPTNO ,30 ,AVGSAL)) 部门30
FROM (
SELECT deptno ,round( AVG(sal)) AVGSAL
FROM emp
GROUP BY deptno );
部门10 ,部门20 ,部门30 全公司
2900 2175 1566 2073
SELECT
MAX(DECODE(DEPTNO ,10 ,AVGSAL)) 部门10,
MIN(DECODE(DEPTNO ,20 ,AVGSAL)) 部门20,
AVG(DECODE(DEPTNO ,30 ,AVGSAL)) 部门30,
MAX(DECODE(DEPTNO ,99 ,AVGSAL)) 全公司
FROM (
SELECT NVL(DEPTNO,99) DEPTNO ,ROUND(AVG(SAL)) AVGSAL
FROM EMP
GROUP BY ROLLUP(DEPTNO) )
子查询
在一个查询语句中嵌套另外一个查询语句,作为前一个查询的字句,这种查询方法叫做子查询
子查询什么时候使用?
1 子查询可以做条件 这种情况是因为过滤条件不明确。
子查询做条件时,有2中情况:
a 子查询返回单行/单个结果 相当于是 =
b 子查询返回单列多行 相当于 in()
c 子查询返回多列多行(表) 同上的逻辑 用 = 或者 in()
2 子查询可以做临时表 构造一个我们需要查询结果集,没有条件创造条件【子查询查出来的表】,来进行辅助查询。