与大多数其他关系数据库产品一样,PolarDB PostgreSQL版(兼容Oracle)也支持聚合函数。聚合函数从多个输入行计算单个结果。例如,有一些聚合可对一组行计算 COUNT、SUM、AVG(平均值)、MAX(最大值)和 MIN(最小值)。

例如,可通过以下查询找到最高和最低工资:

SELECT MAX(sal) highest_salary, MIN(sal) lowest_salary FROM emp;

 highest_salary | lowest_salary
----------------+---------------
        5000.00 |        800.00
(1 row)

如果要找到工资最高的员工,我们可能会尝试以下查询:

SELECT ename FROM emp WHERE sal = MAX(sal);

ERROR:  aggregates not allowed in WHERE clause

此查询无效,因为聚合函数 MAX 不能在 WHERE 子句中使用。存在此限制的原因是,WHERE 子句确定将进入聚合状态的行,因此必须在计算聚合函数之前对该子句进行求值。但是,可通过使用子查询来重新表述该查询以达到预期结果:

SELECT ename FROM emp WHERE sal = (SELECT MAX(sal) FROM emp);

 ename
-------
 KING
(1 row)

子查询是一项独立的计算,它获取自己的结果,与外部查询互不影响。

在与 GROUP BY 子句结合使用时,聚合也十分有用。例如,以下查询获取每个部门中的最高工资。

SELECT deptno, MAX(sal) FROM emp GROUP BY deptno;

 deptno |   max
--------+---------
     10 | 5000.00
     20 | 3000.00
     30 | 2850.00
(3 rows)

此查询为每个部门生成一个输出行。每个聚合结果都是针对与该部门匹配的行计算的。可使用 HAVING 子句筛选这些分组行。

SELECT deptno, MAX(sal) FROM emp GROUP BY deptno HAVING AVG(sal) > 2000;

 deptno |   max
--------+---------
     10 | 5000.00
     20 | 3000.00
(2 rows)

以下查询仅为平均工资高于 2000 的那些部门给出相同的结果。

最后,以下查询仅考虑每个部门中职位为分析师且工资最高的员工。

SELECT deptno, MAX(sal) FROM emp WHERE job = 'ANALYST' GROUP BY deptno HAVING AVG(sal) > 2000;

 deptno |   max
--------+---------
     20 | 3000.00
(1 row)

WHERE 与 HAVING 子句之间存在一个细微的区别。WHERE 子句在执行分组和应用聚合函数之前对行进行筛选。HAVING 子句在对行进行分组并为每个组计算聚合函数后对结果应用筛选条件。

因此,在上一示例中,仅考虑职位为分析师的员工。在此子集中,员工按部门进行分组,最终结果是只有组中分析师的平均工资高于 2000 的那些组。这仅适用于部门 20 组,部门 20 中的分析师最高工资为 3000.00。