📜  使用组功能

📅  最后修改于: 2020-12-29 04:21:02             🧑  作者: Mango


使用组功能报告汇总数据

SQL具有许多预定义的聚合函数,可用于编写查询以生成恰好此类信息。GROUP BY子句指定在聚合信息时如何将数据表中的行分组,而HAVING子句过滤掉不属于该行的行指定的组。

聚合函数执行各种操作,例如对表中的所有行进行计数,对列数据进行平均以及对数字数据求和。聚合还可以搜索表以在列中找到最高的“ MAX”或最低的“ MIN”值。与其他类型的查询一样,您可以使用WHERE子句限制或过滤这些函数所作用的行。例如,如果经理需要知道组织中有多少员工,则可以使用名为COUNT(*)的聚合函数来生成此信息。下面的SELECT语句中显示的COUNT(*)函数对一个组织中的所有行进行计数表。

SELECT COUNT(*)
FROM employees;

  COUNT(*)
----------
        24

COUNT(*)函数的结果表是单行中的一列,称为标量结果或值。请注意,结果表的列标题与SELECT子句中指定的聚合函数的名称相对应。

一些常用的聚合函数如下:

SUM( [ALL | DISTINCT] expression )

AVG( [ALL | DISTINCT] expression )

COUNT( [ALL | DISTINCT] expression )

COUNT(*)

MAX(expression)

MIN(expression)

ALL和DISTINCT关键字是可选的,它们的作用与您所学的SELECT子句相同。ALL关键字是允许使用该选项的默认关键字。语法中列出的表达式可以是常数,函数,或由算术运算运算符连接的列名,常量和函数的任意组合。但是,聚合函数最常与列名一起使用。除COUNT函数,所有聚合函数均不考虑NULL值。

使用聚合时,您必须了解并遵循两个规则:

  • 可以在SELECT和HAVING子句中使用聚合函数(本章稍后将介绍HAVING子句)。

  • 聚合函数不能在WHERE子句中使用。它的违反将产生Oracle ORA-00934组函数,此处不允许出现错误消息。

插图

下面的SELECT查询计算组织中的员工人数。

SELECT COUNT(*) Count
FROM employees;

COUNT
-----
   24

下面的SELECT查询返回组织中员工的平均工资。

SELECT AVG(Salary) average_sal
FROM employees;

AVERAGE_SAL
-----------
      15694

下面的SELECT查询返回组织中员工的薪水总和。

SELECT SUM(Salary) total_sal
FROM employees;

TOTAL_SAL
---------
    87472

下面的SELECT查询返回组织中员工的最旧和最新雇用日期。

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

OLDEST        LATEST
---------    -----------
16-JAN-83    01-JUL-2012

通过…分组

聚合函数通常与GROUP BY子句结合使用。 GROUP BY子句使您可以使用聚合函数来回答更复杂的管理问题,例如:

每个部门员工的平均工资是多少?

每个部门有多少员工?

特定项目中有多少员工?

按函数分组按列建立数据组,并且仅将信息汇总在组内。分组条件由GROUP BY子句中指定的列定义。按照此层次结构,数据首先按组进行组织,然后WHERE子句限制每个组中的行。

使用GROUP BY子句的准则

(1)GROUP BY函数使用的所有从属列或所有列必须构成分组的基础,因此也必须包含在GROUP BY子句中。

SELECT    DEPARTMENT_ID, SUM(SALARY)
FROM employees;

DEPARTMENT_ID,
*
ERROR at line 2:
ORA-00937: not a single-group group function

(2)GROUP BY子句不支持使用列别名,但支持实际名称。

(3)GROUP BY子句只能与SUM,AVG,COUNT,MAX和MIN之类的聚合函数一起使用。如果与单行函数一起使用,Oracle会引发异常,例如“ ORA-00979:不是GROUP BY表达式” 。

(4)聚合函数不能在GROUP BY子句中使用。 Oracle将在此处返回“ ORA-00934:不允许使用组函数”错误消息。

下面的查询列出了每个部门工作的员工人数。

SELECT  DEPARTMENT_ID,  COUNT (*)
FROM employees
GROUP BY DEPARTMENT_ID;

同样,在下面的查询中查找每个部门中各个职位ID的薪金总和。请注意,该组是根据Department和Job ID建立的。因此它们出现在GROUP BY子句中。

SELECT DEPARTMENT_ID, JOB_ID, SUM (SAL)
FROM employees
GROUP BY DEPARTMENT_ID, JOB_ID;

下面的查询也产生相同的结果。请注意,分组是基于“部门ID”和“工作ID”列,但不用于显示目的。

SELECT SUM (SALARY)
FROM employees
GROUP BY DEPARTMENT_ID, JOB_ID;

使用DISTINCT,ALL关键字和聚合函数

通过使用输入参数指定DISTINCT关键字,group by函数仅考虑要聚合的列的唯一值。通过使用输入参数指定ALL关键字,group by函数考虑该列的所有值进行聚合,包括null和重复项。 ALL是默认规范。

HAVING子句

HAVING子句用于聚合函数,其方式与WHERE子句用于列名和表达式的方式相同。本质上,HAVING和WHERE子句具有相同的作用,即根据条件从结果表中过滤行以使其不包含在结果表中。尽管看起来HAVING子句会过滤掉组,但事实并非如此。相反,HAVING子句会过滤行。

总而言之,WHERE和HAVING子句之间的重要区别是:

WHERE子句用于在GROUPING操作之前(即,在计算聚合函数之前)过滤行。

HAVING子句在GROUPING操作之后(即,在计算聚合函数之后)过滤行。

SELECT JOB_ID,    SUM (SALARY)
FROM employees
GROUP BY JOB_ID
HAVING SUM (SALARY) > 10000;

HAVING子句是与GROUP BY子句选项直接相关的条件选项,因为HAVING子句会根据GROUP BY子句的结果从结果表中消除行。

SELECT department_id, AVG(Salary)
FROM employees
HAVING AVG(Salary) > 33000;
ERROR at line 1:  ORA-00937: not a single-group group function