Oracle分组与组函数(二)
条件行的数目。比如:
gyj@OCM> select count(salary) from t1 where salary>5000;
COUNT(SALARY)
-------------
17
统计SALARY列大于5000的行的数目。COUNT(salary)括号中的salary列,可以换为* :
gyj@OCM> select count(*) from t1 where salary>5000;
COUNT(*)
----------
17
换为*后,是统计t1表中,满足salary>5000这个条件的行的数目。这和COUNT(salary)是差不多的。有一点不同,下面我们把条件去掉:
gyj@OCM> select count(*) from t1;
COUNT(*)
----------
22
这将统计t1表中总共有多少行。*号表示,这个统计,是针对所有列的。而如果将COUNT(*)换为COUNT(salary),如下:
gyj@OCM> select count(salary) from t1;
COUNT(SALARY)
-------------
18
这将只统计SALARY列有多少行数据。和其他函数一样,COUNT将忽略空值。
在COUNT中,也可以使用DISTINCT去掉重复值,只统计非重复行的数目:
gyj@OCM> select count(distinct salary) from t1;
COUNT(DISTINCTSALARY)
---------------------
11
在salary列,的确只有11种值。当然,空值仍然不被计算在内,但可以使用NVL将空值转换为0。
四、分组与组函数
1、分组 GROUP BY
分组的语法是:GROUP BY 列名1,列名2,……
分组的作用是根据某些列的值,将这些列值相同的行分为一组。这就是分组。分组和组函数和在一起,可以完成非常强大的功能。组函数从名字上就表现出来了,“组”(重读)函数吗,针对分组的函数。下面我们看一下t3测试表:
gyj@OCM> select * from t3;
ID NAME SALARY
---------- ---------- ----------
1 gyj1 5000
1 gyj11 5000
2 gyj2 6000
2 gyj22 6000
3 gyj3 7000
3 gyj33 7000
4 gyj4 8000
4 gyj44 8000
gyj@OCM> select id,sum(salary) from t3 group by id;
ID SUM(SALARY)
---------- -----------
1 10000
2 12000
4 16000
3 14000
先对t3表的id列进行分组,分组后两个1合并成一个1,两个2合并成一个2,两个3合并成一个3,两个4合并成一个4,所有重复的值都被合并为一个。在分组的同时,使用SUM(SALARY),计算每个小组中薪水的总和。
我们可以在分组时使用所有的组函数,对每一个小组内的数据,分别求和、求平均、最大值、最小值,和统计行数:
gyj@OCM> select id,sum(salary),avg(salary),max(salary),min(salary),count(*) from t3 group by id;
ID SUM(SALARY) AVG(SALARY) MAX(SALARY) MIN(SALARY) COUNT(*)
---------- ----------- ----------- ----------- ----------- ----------
1 10000 5000 5000 5000 2
2 12000 6000 6000 6000 2
4 16000 8000 8000 8000 2
3 14000 7000 7000 7000 2
这个命令中,我使用了我们所讲过的每一个组函数。
在分过组后,非分组列是不能直接显示的,比如:
gyj@OCM> select id,salary from t3 group by id;
select id,salary from t3 group by id
*
ERROR at line 1:
ORA-00979: not a GROUP BY expression
分组后ID被合并成四行,行值分别是1、2、3、4,而SALARY列仍有8行值。这样的话,ORACLE没办法把这两个列组合到一起。因此,就报出了错误。
通常在分组后,在SELECT 和 FROME之间的列名表中,只能出现分组列。要想出现其他列,必须用组函数把列中的行值处理一下,就像上面的例子,SALARY有8行,必须使用组函数,将8行也处理为4行。
gyj@OCM> select id,salary from t3 group by id,salary;
ID SALARY
---------- ----------
1 5000
2 6000
3 7000
4 8000
2、在Group by中使用函数
gyj@OCM> select name from t3 group by substr(name,1,4);
select name from t3 group by substr(name,1,4)
*
ERROR at line 1:
ORA-00979: not a GROUP BY expression
这个命令报出了错误,但是ORACLE已经指出了,错误不在我们的分组子句中,分组子句是对的,分组中可以使用函数。将NAME的前4个字符截取出来,根据这4个字符进行分组,Oracle可以实现这样的功能。错在SELECT 后的列名表NAME上,分组后只剩4个值,而NAME却有8个值。正确的形式是:
gyj@OCM> select substr(name,1,4),count(*) from t3 group by substr(name,1,4);
SUBSTR(N COUNT(*)
-------- ----------
gyj4 2
gyj2 2
gyj1 2
gyj3 2
我同时用COUNT(*)计算一下分组后,每个小组中的行数。
SELECT后的列名表,除了组函数,其他内容必须