前情提要:本篇博客将详细介绍oracle的SQL中的常用聚合函数(SUM AVG MAX MIN COUNT)和分组(GROUP BY)及分组限制(HAVING)的子句、语法、功能和示例详解
oracle版本:19c
一、聚合函数
聚合函数对行进行操作,以使每个组一个结果。

1.1 聚合函数的类型和语法
-
AVG 平均值
-
COUNT 求记录与数据个数
-
MAX 最大值
-
MIN 最小值
-
SUM 求和
-
LISTAGG 行转列函数
-
STDDEV 求标准差
-
VARIANCE 求协方差
-
MEDIAN 求中位数
语法
cpp
SELECT group_function(column), ...
FROM table
[WHERE condition];
1.2 聚合函数使用示例
AVG, MAX, MIN, SUM使用示例
- 可以使用AVG和SUM对数字进行运算
cpp
-- 计算平均工资,最高工资,最低工资,工资总和
SQL> SELECT AVG(salary),MAX(salary),MIN(salary),SUM(salary) FROM employees;
AVG(SALARY) MAX(SALARY) MIN(SALARY) SUM(SALARY)
----------- ----------- ----------- -----------
6461.83178 24000 2100 691416
- 可以使用MIN和MAX在数字、字符与日期类型数据上
cpp
-- 计算最高工资
SQL> SELECT MAX(salary) FROM employees;
MAX(SALARY)
-----------
24000
-- 计算最低工资
SQL> SELECT MIN(salary) FROM employees;
MIN(SALARY)
-----------
2100
-- 判断日期
-- 判断日期标准:哪个日期离当前时间越近,就越大
-- 先修改日期格式方便查看
SQL> ALTER SESSION SET nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
-- 查看最小日期和最大日期
SQL> SELECT MIN(hire_date),MAX(hire_date) FROM employees;
MIN(HIRE_DATE) MAX(HIRE_DATE)
------------------- -------------------
2001-01-13 00:00:00 2008-04-21 00:00:00
COUNT函数使用示例
- COUNT(*)或COUNT(1)返回表中的行数
cpp
SQL> SELECT COUNT(*) FROM employees;
COUNT(*)
----------
107
SQL> SELECT COUNT(1) FROM employees;
COUNT(1)
----------
107
- COUNT(expr)返回expr具有非空值的行数
cpp
-- 表中原本有107行数据,但是COUNT(commission_pct)却只统计出35行,是因为commission_pct中有空值,COUNT不会统计空值
SQL> SELECT COUNT(commission_pct) FROM employees;
COUNT(COMMISSION_PCT)
---------------------
35
-- 如果想统计所有的行,但是又存在空值,则可以使用NVL将空值进行转换
SQL> SELECT COUNT(NVL(commission_pct,0)) FROM employees;
COUNT(NVL(COMMISSION_PCT,0))
----------------------------
107
使用DISTINCT关键字
-
COUNT(DISTINCT expr)返回表达式中的不同非null值的数量。
-
在EMPLOYEES表中显示不同部门值的数量:
cpp
-- 如果不想统计重复值可以使用DISTINCT去重
SQL> SELECT COUNT(department_id),COUNT(DISTINCT DEPARTMENT_ID) FROM EMPLOYEES;
COUNT(DEPARTMENT_ID) COUNT(DISTINCTDEPARTMENT_ID)
-------------------- ----------------------------
106 11
-- 不去重统计department_id有106行,去重后只有11行了
聚合函数和NULL值
- 忽略列中的NULL值
cpp
-- 使用AVG计算commission_pct,但是由于commission_pct存在空值会被忽略,导致结果不准确
SQL> SELECT AVG(commission_pct) FROM employees;
AVG(COMMISSION_PCT)
-------------------
.222857143
- 使用NVL函数强制将列中的NULL值进行转换
cpp
SQL> SELECT AVG(NVL(commission_pct,0)) FROM employees;
AVG(NVL(COMMISSION_PCT,0))
--------------------------
.0728971963
二、分组
对数据进行分组

按多列分组

GROUP BY子句语法
cpp
SELECT column, group_function(column)
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[ORDER BY column];
2.1 GROUP BY 子句
SELECT列表中所有不在分组(聚合)函数中的列必须在GROUP BY子句中
GROUP BY列不必在SELECT列表中
示例
- 按照DEPARTMENT_ID【部门编号】进行分组,分组以后求每个部门的平均工资
cpp
SQL> SELECT department_id, AVG(salary) FROM employees GROUP BY department_id; -- 先分组再聚合
DEPARTMENT_ID AVG(SALARY)
------------- -----------
50 3475.55556
40 6500
110 10154
90 19333.3333
30 4150
70 10000
7000
10 4400
20 9500
60 5760
100 8601.33333
DEPARTMENT_ID AVG(SALARY)
------------- -----------
80 8955.88235
12 rows selected.
- 按照部门分组后再按照岗位分组,最后求不同部门的不同岗位的平均工资并且按照部门升序排序
cpp
SQL> SELECT department_id,job_id,SUM(salary)
2 FROM employees
3 WHERE department_id>40
4 GROUP BY department_id,job_id
5 ORDER BY department_id;
DEPARTMENT_ID JOB_ID SUM(SALARY)
------------- ---------- -----------
50 SH_CLERK 64300
50 ST_CLERK 55700
50 ST_MAN 36400
60 IT_PROG 28800
70 PR_REP 10000
80 SA_MAN 61000
80 SA_REP 243500
90 AD_PRES 24000
90 AD_VP 34000
100 FI_ACCOUNT 39600
100 FI_MGR 12008
DEPARTMENT_ID JOB_ID SUM(SALARY)
------------- ---------- -----------
110 AC_ACCOUNT 8300
110 AC_MGR 12008
13 rows selected.
- 求部门的平均工资
cpp
-- GROUP BY 列不必在SELECT列表中
SQL> SELECT AVG(salary)
2 FROM employees
3 GROUP BY department_id;
AVG(SALARY)
-----------
3475.55556
6500
10154
19333.3333
4150
10000
7000
4400
9500
5760
8601.33333
AVG(SALARY)
-----------
8955.88235
12 rows selected.
-- 但是SELECT列中不在聚合函数中的列必须在GROUP BY列中
SQL> SELECT department_id,AVG(salary)
2 FROM employees
3* GROUP BY department_id;
DEPARTMENT_ID AVG(SALARY)
------------- -----------
50 3475.55556
40 6500
110 10154
90 19333.3333
30 4150
70 10000
7000
10 4400
20 9500
60 5760
100 8601.33333
DEPARTMENT_ID AVG(SALARY)
------------- -----------
80 8955.88235
12 rows selected.
2.2 使用聚合函数的非法查询
SELECT列表中不是聚合函数的任何列或表达式都必须在GROUP BY子句中:
错误示例
cpp
SQL> SELECT department_id,COUNT(last_name)
2 FROM employees;
SELECT department_id,COUNT(last_name)
*
ERROR at line 1:
ORA-00937: not a single-group group function
-- 必须添加GROUP BY子句以计算每个department_id的last_name。
SQL> SELECT department_id,job_id,COUNT(last_name)
2 FROM employees
3 GROUP BY deepartment_id;
GROUP BY deepartment_id
*
ERROR at line 3:
ORA-00904: "DEEPARTMENT_ID": invalid identifier
-- 在GROUP BY中添加job_id或从SELECT列表中删除job_id列。
-
您不能使用WHERE子句来限制组。
-
您可以使用HAVING子句来限制组。
-
您不能在WHERE子句中使用聚合函数。
错误示例
cpp
SQL> SELECT department_id,AVG(salary)
2 FROM employees
3 WHERE AVG(salary) > 8000
4 GROUP BY department_id;
WHERE AVG(salary) > 8000
*
ERROR at line 3:
ORA-00934: group function is not allowed here
-- 不能使用WHERE子句来限制分组
2.3 使用HAVING子句限制分组结果集

当您使用HAVING子句时,Oracle服务器对组的限制如下:
1.行被分组。
2.应用分组功能。
3.显示与HAVING子句匹配的组。
使用HAVING的限制
-
不能引用非分组列:HAVING条件中不能使用未在GROUP BY中指定的列
-
不能使用别名:不能直接使用SELECT子句中定义的别名,必须使用原始列名或聚合函数
-
不能包含子查询:HAVING条件中不能嵌套子查询
语法
cpp
SELECT column, group_function
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY column];
使用HAVING子句示例
- 查看平均工资大于8000的部门
cpp
SQL> SELECT department_id,AVG(salary)
2 FROM employees
3 GROUP BY department_id
4 HAVING AVG(salary)>8000;
DEPARTMENT_ID AVG(SALARY)
------------- -----------
110 10154
90 19333.3333
70 10000
20 9500
100 8601.33333
80 8955.88235
6 rows selected.
- 查询工资总和大于13000且不含'REP'字符的岗位,并且按照工资总和升序排序
cpp
SQL> SELECT job_id,SUM(salary) PAYROLL
2 FROM employees
3 WHERE job_id NOT LIKE '%REP%'
4 GROUP BY job_id
5 HAVING SUM(salary)>13000
6 ORDER BY SUM(salary);
JOB_ID PAYROLL
---------- ----------
PU_CLERK 13900
AD_PRES 24000
IT_PROG 28800
AD_VP 34000
ST_MAN 36400
FI_ACCOUNT 39600
ST_CLERK 55700
SA_MAN 61000
SH_CLERK 64300
9 rows selected.
三、嵌套聚合函数
聚合函数可以嵌套使用
示例
- 显示最高平均工资
cpp
SQL> SELECT MAX(AVG(salary))
2 FROM employees
3 GROUP BY department_id;
MAX(AVG(SALARY))
----------------
19333.3333