Oracle

1、统计计算函数

相对于单行函数,也可称之为多行函数,它的输入是多个行构成得一个行集(这个行集可以是 一张表的所有行,也可以是按照某个维度进行分组后的某一组行),而输出都是一个值; 比如常见的一些分组计算需求:求某个部门的薪资总和,薪资平均值,薪资最大值等等。

  1. 求和 (SUM)
  2. 求平均值(AVG)
  3. 计数(COUNT)
  4. 求标准差(STDDEV)
  5. 求方差(VARIANCE)
  6. 求最大值(MAX)
  7. 求最小值(MIN) ```sql 遍历表的各行数据,统计完后再返回结果

    sum

    1 求员工工资总和

    1. select sum(sal) from emp;

    count

    1 求员工数量,有奖金的员工数

    1. select count(*) 员工数量, count(comm) from emp
    2. count(*) 只要一行有数据就统计
    3. count(comm) 只有comm 不是null才统计
    4. 【结论】:NULL不会参与统计函数的统计

    2 求工作岗位数量 统计去重

    1. select count(distinct job) from emp;

max/min

  1. 求员工最高工资和最低工资

avg

  1. 求员工平均工资
  2. select avg(sal) from emp;
  3. 求员工平均奖金(三种方式)
  4. select avg(comm) ,sum(comm)/count(*) ,sum(comm)/count(comm) from emp;
  1. <a name="aQhHE"></a>
  2. ### A、SQL中使用分组计算函数的语法
  3. ```sql
  4. SELECT [column,] group_function(column), ...
  5. FROM table
  6. [WHERE condition]
  7. [GROUP BY column]
  8. [ORDER BY column];

B、AVG、MAX、MIN、SUM对数值进行计算

  1. SELECT AVG(salary), MAX(salary), MIN(salary), SUM(salary)
  2. FROM employees
  3. WHERE job_id LIKE '%REP%';

image.png

C、MAX、MIN对日期进行计算

  1. SELECT MIN(hire_date), MAX(hire_date)
  2. FROM employees;

image.png :::danger 备注:MIN,MAX 可用于任何数据类型,但AVG , SUM,STDDEV,VARIANCE仅适用于数值型字段。 :::

D、COUNT函数

函数用法 意义
COUNT(*) 返回满足选择条件的所有行的行数,包括值为空的行和重复的行。
COUNT(expr) 返回满足选择条件的且表达式不为空行数。
COUNT(DISTINCT expr) 返回满足选择条件的且表达式不为空,且不重复的行数。

**SELECT COUNT(1)****SELECT COUNT(*)**, **SELECT COUNT(column1)** 返回的结果一样

2、使用GROUP BY子句进行分组统计

  1. select ...
  2. from ...
  3. where ...
  4. group by 1,列2.... --根据某列、多列进行分组
  5. having cond
  6. order by
  7. 1 查询各部门平均工资
  8. select deptno , avg(sal)
  9. from emp
  10. group by deptno
  11. 【结论】:统计函数在有分组的情况下,统计的就是每个分组里边多行数据
  12. 没有分组的情况下,就是统计全表
  13. select 中出现的列,必须在group by中出现 ,除了统计函数
  14. 2 查询平均薪水大于2000的部门
  15. select deptno , avg(sal)
  16. from emp
  17. where avg(sal) > 2000
  18. group by deptno
  19. 3 行出现错误:
  20. ORA-00934: 此处不允许使用分组函数
  21. where 里边不允许使用分组函数进行判断
  22. 使用having
  23. select deptno , avg(sal)
  24. from emp
  25. group by deptno
  26. having avg(sal) > 2000
  27. 3 10号部门员工的平均薪水
  28. select deptno , avg(sal)
  29. from emp
  30. where deptno = 10
  31. group by deptno
  32. having
  33. select deptno , avg(sal)
  34. from emp
  35. group by deptno
  36. having deptno = 10
  37. 4 havingwhere的区别
  38. select ..
  39. from emp
  40. where cond
  41. group ...
  42. havin cond
  43. order by ...
  44. where能做的having也能做,where不能做的having也能做
  45. 结论:能用where就别用having
  46. 1 from 的表 emp 拿出数据
  47. 2 逐行筛选,通过where条件来筛选 结果集1
  48. 3 分组,并且计算统计函数 ,结果集2
  49. 4 再进行筛选,having的条件,通过having的条件就留下,得到结果集3
  50. 5 排序 得到结果集
  51. 如果一开始不通过where筛选,后边计算量大

1.可以按照某一个字段分组,也可以按照多个字段的组合进行分组

  1. SELECT department_id, AVG(salary) FROM employees
  2. GROUP BY department_id;

image.png

  1. SELECT department_id dept_id, job_id, SUM(salary),AVG(salary)
  2. FROM employees
  3. GROUP BY department_id, job_id;

image.png

2.SELECT 查询语句中同时选择分组计算函数表达式和其他独立字段时 ,其他字段必须出现在Group By子 句中,否则不合法。

错误的写法

  1. SELECT department_id, COUNT(last_name)
  2. FROM employees;

image.png

正确的写法

  1. SELECT department_id, count(last_name) FROM employees
  2. GROUP BY department_id;

image.png

3.不能在Where 条件中使用分组计算函数表达式,当出现这样的需求的时候,使用Having 子句。

错误写法

  1. SELECT department_id, AVG(salary) FROM employees
  2. WHERE AVG(salary) > 8000
  3. GROUP BY department_id;

image.png

正确的写法

  1. SELECT department_id, AVG(salary) FROM employees
  2. GROUP BY department_id
  3. HAVING AVG(salary) > 8000;

image.png

4.分组计算函数也可嵌套使用

  1. SELECT MAX(AVG(salary))
  2. FROM employees
  3. GROUP BY department_id;

image.png

3、GROUP BY语句增强

A.使用Rollup产生常规分组汇总行以及分组小计

  1. SELECT department_id, job_id, SUM(salary)
  2. FROM employees
  3. WHERE department_id < 60
  4. GROUP BY ROLLUP(department_id, job_id);

image.png
image.png
Rollup 后面跟了n个字段,就将进行n+1次分组,从右到左每次减少一个字段进行分组;然后进行 union

B.Cube产生Rollup结果集+多维度的交叉表数据源

  1. SELECT department_id, job_id, SUM(salary)
  2. FROM employees
  3. WHERE department_id < 60
  4. GROUP BY CUBE (department_id, job_id) ;

image.pngimage.png
image.png

C.GROUPING函数

Rollup 和 Cube有点抽象,他分别相当于n+1 和 2的n次方常规 Group by 运 算;那么在Rollup 和 Cube的结果集中如何很明确的看出哪些行是针对那些列或者列的组合进行 分组运算的结果的? 答案是可以使用Grouping 函数; 没有被Grouping用到返回1,否则返回0

  1. SELECT department_id DEPTID, job_id JOB,
  2. SUM(salary),
  3. GROUPING(department_id) GRP_DEPT,
  4. GROUPING(job_id) GRP_JOB
  5. FROM employees
  6. WHERE department_id < 50
  7. GROUP BY ROLLUP(department_id, job_id);

image.png

D.使用Grouping Set来代替多次UNION

  1. SELECT department_id, job_id,
  2. manager_id,avg(salary)
  3. FROM employees
  4. GROUP BY GROUPING SETS
  5. ((department_id,job_id), (job_id,manager_id));

image.png
image.png
image.png