• 是对一组数据进行汇总的函数,输入的是一组数据的集合,输出的是单个值
  • 聚合函数不能嵌套调用

    常见的聚合函数

    AVG和SUM函数

    对数值型数据使用,过滤空值

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

    MIN和MAX函数

    可以对任意数据类型的数据使用,过滤空值

    SELECT MIN(hire_date), MAX(hire_date)
    FROM employees;
    

    COUNT函数

  • COUNT(*)返回表中记录总数,适用于任意数据类型

  • COUNT(expr)返回expr不为空的记录总数
  • COUNT(1)返回表中记录总数 ```sql SELECT COUNT(*) FROM employees WHERE department_id = 50;

SELECT COUNT(commission_pct) FROM employees WHERE department_id = 50;

<a name="po6vd"></a>
### GROUP BY
<a name="WMUYG"></a>
#### 使用单个列分组
```sql
SELECT department_id, AVG(salary), MAX(salary)
FROM employees
GROUP BY department_id;

使用多个列分组

SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id, job_id;

注意:在SELECT列表中所有未包含在组函数中的字段都应该包含在GROUP BY子句中,但是包含在GROUP BY子句中的字段不必包含在SELECT列表中

SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id;

GROUP BY中使用WITH ROLLUP

使用WITH ROLLUP关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算查询出的所有记录的组函数

SELECT department_id, AVG(salary)
FROM employees
WHERE department_id > 80
GROUP BY department_id WITH ROLLUP;

说明:当使用ROLLUP时,不能同时使用ORDER BY子句对结果进行排序,即ROLLUP和ORDER BY是互相排斥的

HAVING

基本使用

  • 如果过滤条件中使用了聚合函数,则必须使用HAVING来替换WHERE,否则会报错
  • 通常HAVING不能单独使用,要跟GROUP BY一起使用
  • HAVING必须声明在GROUP BY的后面 ```sql //查询各个部门中最高工资比10000高的部门信息 //错误写法 SELECT department_id, MAX(salary) FROM employees WHERE MAX(salary) > 10000 GROUP BY department_id;

//正确写法 SELECT department_id, MAX(salary) FROM employees GROUP BY department_id HAVING MAX(salary) > 10000;

//查询部门id为10、20、30、40这四个部门中最高工资比10000高的部门信息 //方式一,推荐使用,因为执行效率更高 SELECT department_id, MAX(salary) FROM employees WHERE department_id IN (10, 20, 30, 40) GROUP BY department_id HAVING MAX(salary) > 10000;

//方式二 SELECT department_id, MAX(salary) FROM employees GROUP BY department_id HAVING MAX(salary) > 10000 AND department_id IN (10, 20, 30, 40);

<a name="L4SPI"></a>
#### WHERE和HAVING的对比

- 当过滤条件中有聚合函数时,则此过滤条件必须声明在HAVING中
- 当过滤条件中没有聚合函数时,则此过滤条件声明在WHERE中或HAVING中都可以。但是,建议声明在WHERE中
<a name="aKz3y"></a>
### SELECT的执行过程
<a name="zezoa"></a>
#### 查询结构
```sql
//sql92语法
SELECT...
FROM...
WHERE 多表的连接条件
AND 不包含聚合函数的过滤条件
GROUP BY...
HAVING 包含聚合函数的过滤条件
ORDER BY...ASC/DESC
LIMIT...

//sql99语法
SELECT...
FROM...(LEFT/RIGHT)JOIN...ON 多表的连接条件
(LEFT/RIGHT)JOIN...ON 多表的连接条件
WHERE 不包含聚合函数的过滤条件
AND/OR 不包含聚合函数的过滤条件
GROUP BY...
HAVING 包含聚合函数的过滤条件
ORDER BY...ASC/DESC
LIMIT...

执行顺序:

FROM --> ON --> (LEFT/RIGHT JOIN) --> WHERE --> GROUP BY --> HAVING --> SELECT --> DISTINCT --> ORDER BY --> LIMIT