首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

Oracle DB 对行进展分组-group by、having

2013-10-22 
Oracle DB 对行进行分组-group by、having创建数据组所有组函数都将表当作一个大型的信息组。但是,有时需要

Oracle DB 对行进行分组-group by、having


创建数据组所有组函数都将表当作一个大型的信息组。但是,有时需要将此信息表分成几个较小的组。可以通过使用GROUP BY子句完成此任务。
创建数据组:GROUP BY子句的语法可以通过使用GROUP BY子句将表中的行分成较小的组。SELECT  column, group_function(column)FROM  table[WHERE  condition][GROUP BY group_by_expression][ORDER BY column];

可以使用GROUP BY子句将表中的行分成组。然后,可以使用组函数返回每个组的汇总信息。在该语法中:group_by_expression 指定某些列,这些列的值确定对行进行分组的基准准则? 除非在GROUP BY子句中指定了单个列,否则即使在SELECT子句中包括组函数,也不能选择单个结果。如果未在GROUP BY子句中包括列的列表,则会收到一条错误消息。? 通过使用WHERE子句,可以在将行分成多个组之前先排除某些行。? 必须将列包括在GROUP BY子句中。? 不能在GROUP BY子句中使用列别名。
使用GROUP BY子句SELECT列表中未出现在组函数中的所有列都必须包含在GROUP BY子句中。hr@TEST0924> SELECT department_id, AVG(salary) FROM employees GROUP BY department_id ;
DEPARTMENT_ID AVG(SALARY)------------- -----------          100  8601.33333           30        4150                     7000           20        9500           70       10000           90  19333.3333          110       10154           50  3475.55556           40        6500           80  8955.88235           10        4400           60        5760
12 rows selected.
使用GROUP BY子句时,应确保将SELECT列表中未出现在组函数中的所有列都包含在GROUP BY子句中。示例显示每个部门的部门编号和平均薪金。下面介绍含有GROUP BY子句的SELECT语句是如何进行求值的:? SELECT:子句指定要检索的列,如下所示:- EMPLOYEES:表中的部门编号列- GROUP BY:子句指定的组中所有薪金的平均值? FROM:子句指定数据库必须访问的表:EMPLOYEES表。? WHERE:子句指定要检索的行。由于没有WHERE子句,默认情况下会检索所有行。? GROUP BY:子句指定如何对行进行分组。由于是按部门编号对行进行分组,因此应用于薪金列的AVG函数会计算每个部门的平均薪金。注:要按升序或降序对查询结果进行排序,请在查询中包含ORDER BY子句。
使用GROUP BY子句GROUP BY列不一定要出现在SELECT列表中。hr@TEST0924> SELECT AVG(salary) FROM employees GROUP BY department_id ;
AVG(SALARY)----------- 8601.33333       4150       7000       9500      10000 19333.3333      10154 3475.55556       6500 8955.88235       4400       5760
12 rows selected.

GROUP BY列不一定要出现在SELECT子句中。例如,示例中的SELECT语句显示每个部门的平均薪金,但没有显示相应的部门编号。但是如果没有部门编号,结果看起来毫无意义。也可以在ORDER BY子句中使用组函数:hr@TEST0924> SELECT department_id, AVG(salary) FROM employees GROUP BY department_id ORDER BY AVG(salary);
DEPARTMENT_ID AVG(SALARY)------------- -----------           50  3475.55556           30        4150           10        4400           60        5760           40        6500                     7000          100  8601.33333           80  8955.88235           20        9500           70       10000          110       10154           90  19333.3333
12 rows selected.
按多个列进行分组有时,需要查看组内的各个组的结果。hr@TEST0924> SELECT department_id, job_id, sum(salary) FROM employees GROUP BY department_id, job_id ORDER BY job_id;
DEPARTMENT_ID JOB_ID     SUM(SALARY)------------- ---------- -----------          110 AC_ACCOUNT        8300          110 AC_MGR           12008           10 AD_ASST           4400...20 rows selected.

此示例显示一个报表,其中显示要付给各个部门中每种职务的薪金总和。EMPLOYEES表首先按部门编号进行分组,然后在各个组中又按职务进行分组。例如,将部门50 中的四个仓储职员分成一个组,并为该组中的所有仓储职员生成一个结果(薪金总和)。



对多个列使用GROUP BY子句hr@TEST0924> SELECT department_id, job_id, SUM(salary) FROM employees WHERE department_id > 40 GROUP BY department_id, job_id  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          110 AC_ACCOUNT        8300          110 AC_MGR           12008
13 rows selected.通过列出多个GROUP BY列,可以返回组和子组的汇总结果。GROUP BY子句对行进行分组,但不保证结果集的顺序。要对组进行排序,请使用ORDER BY子句。在示例中,包含GROUP BY子句的SELECT语句按如下方式进行求值:? SELECT子句指定要检索的列:- EMPLOYEES表中的部门ID - EMPLOYEES表中的职务ID - GROUP BY子句指定的组中所有薪金的总和? FROM子句指定数据库必须访问的表:EMPLOYEES表。? WHERE子句将结果集限定为部门ID 大于40 的行。? GROUP BY子句指定应如何对结果行进行分组:- 首先,按部门ID 对行进行分组- 其次,在部门ID 组中按职务ID 对行进行分组? ORDER BY子句按部门ID 对结果进行排序。注:SUM函数将应用于每个部门ID 组的结果集中所有职务ID 的薪金列。另外,请注意,不返回SA_REP 行。此行的部门ID 为NULL,因此不满足WHERE条件。
使用组函数的非法查询SELECT列表中不在聚集函数中的任何列或表达式都必须出现在GROUP BY子句中:hr@TEST0924> SELECT department_id, COUNT(last_name) FROM employees;SELECT department_id, COUNT(last_name) FROM employees       *ERROR at line 1:ORA-00937: not a single-group group function必须添加GROUP BY子句,才能对每个department_id对应的姓氏进行计数。
hr@TEST0924> SELECT department_id, job_id, COUNT(last_name) FROM employees GROUP BY department_id;SELECT department_id, job_id, COUNT(last_name) FROM employees GROUP BY department_id                      *ERROR at line 1:ORA-00979: not a GROUP BY expression
要么在GROUP BY中添加job_id,要么从SELECT列表中删除job_id列。


只要在同一个SELECT语句中混合使用单个项(DEPARTMENT_ID) 和组函数(COUNT),就必须包括一个指定这些单个项(本例中为DEPARTMENT_ID)的GROUP BY子句。如果缺少GROUP BY子句,则会出现错误消息“not a single-group group function(不是一个组的组函数)”,而且显示一个指向错误列的星号(*)。可通过添加GROUP BY子句更正第一个示例中的错误:hr@TEST0924> SELECT department_id, count(last_name) FROM employees GROUP BY department_id;
DEPARTMENT_ID COUNT(LAST_NAME)------------- ----------------          100                6           30                6                             1           20                2           70                1           90                3          110                2           50               45           40                1           80               34           10                1           60                5
12 rows selected.
SELECT列表中不在聚集函数中的任何列或表达式都必须出现在GROUP BY子句中。
在第二个示例中,job_id既不在GROUP BY子句中也不在组函数中,因此将出现“not a GROUP BYexpression(不是GROUP BY表达式)”错误。可通过在GROUP BY子句中添加job_id更正第二个示例中的错误。hr@TEST0924> SELECT department_id, job_id, COUNT(last_name) FROM employees GROUP BY department_id, job_id;
DEPARTMENT_ID JOB_ID     COUNT(LAST_NAME)------------- ---------- ----------------          110 AC_ACCOUNT                1           90 AD_VP                     2           50 ST_CLERK                 20...20 rows selected.

使用组函数的非法查询? 不能使用WHERE子句限定组。hr@TEST0924> SELECT department_id, AVG(salary) FROM employees WHERE  AVG(salary) > 8000 GROUP BY department_id;SELECT department_id, AVG(salary) FROM employees WHERE  AVG(salary) > 8000 GROUP BY department_id                                                        *ERROR at line 1:ORA-00934: group function is not allowed here

? 可以使用HAVING子句限定组。? 不能在WHERE子句中使用组函数。
不能使用WHERE子句限定组。示例中的SELECT语句产生了一个错误,因为该语句使用WHERE子句限定显示平均薪金大于$8,000 的那些部门的平均薪金。但是,通过使用HAVING子句限定组,可以更正该示例中的错误:hr@TEST0924> SELECT department_id, AVG(salary) FROM employees GROUP BY department_id HAVING AVG(salary) > 8000;
DEPARTMENT_ID AVG(SALARY)------------- -----------          100  8601.33333           20        9500           70       10000           90  19333.3333          110       10154           80  8955.88235
6 rows selected.
限定组结果与使用WHERE子句限定所选行的方式相同,可以使用HAVING子句限定组。要在最高薪金大于$10,000 的每个部门中查找最高薪金,需要执行以下操作:1.通过按部门编号进行分组,查找每个部门的最高薪金。2.将组限定为最高薪金大于$10,000 的部门。
使用HAVING子句限定组结果使用HAVING子句时,Oracle Server 将按以下方式对组进行限定:1. 对行进行分组。2. 应用组函数。3. 显示符合HAVING子句的组。SELECT  column, group_functionFROM  table[WHERE  condition][GROUP BY group_by_expression][HAVING  group_condition][ORDER BY column];
可使用HAVING子句指定要显示的组,该子句基于汇总信息进一步限定组。在上述语法中,group_condition用于限定满足指定条件的组的返回行组。使用HAVING子句时,Oracle Server 会执行以下步骤:1.对行进行分组。2.对组应用组函数。3.显示符合HAVING子句中的标准的组。HAVING子句可放在GROUP BY子句之前,但建议将GROUP BY子句放在前面,因为这样更符合逻辑。应先形成组并计算组函数,然后再对SELECT列表中的组应用HAVING子句。注:WHERE子句限定行,而HAVING子句限定组。
使用HAVING子句hr@TEST0924> SELECT department_id, MAX(salary) FROM employees GROUP BY department_id HAVING MAX(salary)>10000 ;
DEPARTMENT_ID MAX(SALARY)------------- -----------          100       12008           30       11000           20       13000           90       24000          110       12008           80       14000
6 rows selected.
示例显示最高薪金大于$10,000 的部门的部门编号和最高薪金。可以在SELECT列表中使用GROUP BY子句,而不使用组函数。如果根据组函数的结果来限定行,则必须采用GROUP BY子句和HAVING子句。下面的示例显示最高薪金大于$10,000 的部门的部门编号和平均薪金:hr@TEST0924> SELECT department_id, AVG(salary) FROM employees GROUP BY department_id HAVING max(salary)>10000;
DEPARTMENT_ID AVG(SALARY)------------- -----------          100  8601.33333           30        4150           20        9500           90  19333.3333          110       10154           80  8955.88235
6 rows selected.
使用HAVING子句hr@TEST0924> SELECT job_id, SUM(salary) PAYROLL FROM employees WHERE job_id NOT LIKE '%REP%' GROUP BY job_id HAVING SUM(salary) > 13000 ORDER BY SUM(salary);
JOB_ID        PAYROLL---------- ----------PU_CLERK        13900AD_PRES         24000IT_PROG         28800AD_VP           34000ST_MAN          36400FI_ACCOUNT      39600ST_CLERK        55700SA_MAN          61000SH_CLERK        64300
9 rows selected.
示例显示工资合计超过$13,000 的每个职务的职务ID 和月薪总额。该示例将销售代表排除在外,而且按月薪总额对列表进行排序。 嵌套组函数下列语句显示最高平均薪金:hr@TEST0924> SELECT  MAX(AVG(salary)) FROM employees GROUP BY department_id;
MAX(AVG(SALARY))----------------      19333.3333
组函数可以嵌套两层。示例计算每个department_id对应的平均薪金,然后显示最高平均薪金。请注意,嵌套组函数时,必须使用GROUP BY子句。

热点排行