关于使用count(X) 函数的说明(附加:关于null的说明以及和0的区别)

原创 2013年12月05日 11:13:19
关于使用count(X) 函数的说明

count(X) 函数用于计算一个查询所返回的行数,但是和其他的聚合函数AVG(X), SUM(X), MAX(X), MIN(X)一样,它在统计的时候都会简单的忽略含有空记录的查询,即count(X)中的表达式X的值为null时,count(X)(的返回值)为0。

例如,假设表test的内容如下:

select   *  from test;

ID   NAME        COUNTRY

---          ------------     ----------------

1            tone            china

2             lily             america

1            tone            america

null         null             null

null         null             null

3            null             china

SQL>select t.* ,count(name)from test t group by id,name;

ID   NAME        COUNT(NAME)

---          ------------     ----------------

1            tone           2

2             lily             america

null         null             0

3            null             0

虽然(id,name)=(3 , null  )这一组有一行,(id,name)=(null , null  )这一组有两行,但是由于他们在name这一列值都是为null,所以count(name)的值就是0。同时,也说明虽然(id,name)=(null , null  )这一组id和name值都是null,但是group by不会忽略该空记录

SQL>select t.* ,count(*)from test t group by id,name;

ID   NAME        COUNT(*NAME

---          ------------     ----------------

1            tone           2

2             lily             america

null         null             2

3            null             1

我们发现,使用count(*)时,(id,name)=(null , null  )这一组的count(*name)的值就=为2,说明此时count(*)里的*所代表的表达式的值不为null也就是说*不等价于表里的所有列的值(如果该值的数据类型不是字符类型,应该都会隐式转换为字符)连接成的字符串,具体到表test上,就是*不等价于id||name||country。


count(X) 函数里的参数个数只有一个所以类似count(id,name) 时,就会提示“参数个数无效”。参数值为null时就不统计该值的。若想在count(X) 函数里出现表的多个字段,则使用如下方式:

例如,表test有字段ID,NAME ,COUNTRY,我们想在count(X) 函数里出现表test的ID,NAME 字段,则用count(id||name)的形式。其中,id||name就是一个参数,id和name同时为null,则id||name也为null,故而被count(X) 函数统计。||是字符串连接符,连接多个字符串组成一个新的字符串。具体结果如下:

SQL>select t.* ,count(id||name) from test t group by id,name;

ID   NAME        COUNT(ID||NAME)

---          ------------     ----------------

1            tone           2

2             lily             america

null         null             0

3            null             1


总结:


1、count(column)不统计null。

count(*) 和count(rowid)没有类似的问题,不会只统计非空记录。也可以用例如count(1),count(数字或是字符常量或是字符串常量),不过還是用rowid快。



COUNT(*) operation countsall rows fed to it by execution plan branch under it.

COUNT(*) operation统计表对应的段中所有的数据行(包括其上各列的值为空值null的数据行)

COUNT(column) operation on the other handcountsall non-null values in that column from rows fed to it by execution plan branch under it.

COUNT(column) operation统计表对应的段中其列上的值不为空值null的数据行

注释:COUNT(column)的一般形式为COUNT(column1||column2||......)。


参见:

Select COUNT(*) and COUNT(column) are different things!


疑问:

在同一张表上,Count(*)和count(常量)如count(1),count(‘f’)两种形式的写法统计出来的结果都是一致的,能说明Count(*)和count(常量)如count(1),count(‘f’)等的原理是一样的?

这个要看具体的执行计划。

参见:

differenct between count(0), count(1) and count(*)[哪个执行速度快?]



2、count(*)查询所消耗的时间比count(rowid) 长吗?


count(*)也并不比count(rowid)慢,某些情况下比count(rowid)还要快得多,这个要看具体的执行计划。

count(*)时走全表扫描方式,count(rowid)时索引范围扫描??)

参见:

differenct between count(0), count(1) and count(*)[哪个执行速度快?]


https://community.oracle.com/thread/523654?start=15&tstart=0

http://oracledba.co.uk/tips/count_speed.htm

3、关于*的疑问:

select   *  from test;

ID   NAME       COUNTRY

貌似说明,*等价于id||name||country

SQL>select t.* ,count(*)from test t group by id,name;

ID   NAME       COUNT(*NAME

---         ------------     ----------------

1           tone           2

2            lily            america

null        null             2

3           null             1

我们发现,使用count(*)时,(id,name)=(null , null  )这一组的count(*name)的值就=为2,说明此时count(*)里的*所代表的表达式的值不为null,也就是说*不等价于表里的所有列的值(如果该值的数据类型不是字符类型,应该都会隐式转换为字符)连接成的字符串,具体到表test上,就是*不等价于id||name||country。

 

那么,*具体代表什么呢?*等价于id||name||country||rowid?*等价于id||name||country||rowid||rownum?

Select    a.* ,count(b.*) from   t1 a ,t2 b  (where a.id=b.id(+));

出现错误:ORA01747: invalid user.table.column, table.column, orcolumnspecification

注释:user.table.column, table.column, orcolumn是一个列名的三种不同的写法。

Select     count(b.*) from t2 b;

Select     count(t2.*) from t2;

出现错误:ORA01747: invalid user.table.column, table.column, orcolumnspecification

注释:user.table.column, table.column, orcolumn是一个列名的三种不同的写法。

 

回答:

两处中的*含义不一样的,没有统一的一个意思:

在SQL语句中的*表示表的所有列,即假如表test有id、name和country三个列,则select * from test等于select id,name,countryfrom test,即*等于表示id,name,country(这个字符串在一条sql语句这种字符串中)

 

设计编程count(X)函数时,参数值*,表示统计表对应的段中所有的数据行(包括其上各列的值为空值null的数据行)。而设计编程count(X)函数时,将参数值A.B的形式规定为表A上的列B的意思,故count(X)函数中的参数值为b.*时,count(X)函数就将其解释为表b中的一列名为*的列,而实际上表b中不存在一列名为*的列,所以提示ORA-01747: 指定的列名无效(invalid user.table.column, table.column, orcolumn specification)。这是设计函数时没考虑b.*的形式而造成的结果。


附加:

关于null的说明以及和0的区别

一个变量(例如,表上的各个列其实本质就是一个个变量)的值为null(即数据(值)为空),表示该变量没有被赋予任何数值。换句话说,当一个变量的值为null时,表示该变量还不知道自己的值为多少,它的值可能是任一数值中的一个。所以说,一个变量的值为null,不等价于一个变量的值为0。一个变量的值为null,不等于说,就不用占用存储空间来存放null这个变量赋值中的一种状态。例如,表test1上有一个数据行,其上的各列的值皆为null:

insert into test1 values(null,null,null);//这里的null是个关键字,不是insert into test1 values(‘null’,‘null’,‘null’),这个是插入一行各列的值是字符串值为null这些字符的数据行。

则不是说该表对应的段上的数据块里不用消耗一定存储空间来存储该行的数据的,而还要的,即占据了一数据行的存储空间,只是存储的值不为什么数值,为空值。

 

 附加2:


当表t2里不含有数据行即0条数据行时,count(*)的返回值为0;

当表t3里有2行数据如下:

id1    id2

----     -----

null   2

null   2

则select count(id1) from t3 where id2=2里count(id1)的返回值为0

 


参考:

关于null的说明以及和0的区别

Oracle query - how to make count to return values with 0







相关文章推荐

使用COUNT函数处理NULL值

使用COUNT函数处理NULL值 大部分集合函数在进行计算时都去除NULL值,但COUNT函数是一个例外。一般情况下当对一个包含NULL值的列使用COUNT函数时,这个列中的NULL值将会被去除掉。...
  • li19236
  • li19236
  • 2014年11月25日 18:05
  • 1142

关于count函数返回null值

SELECT count(1) FROM sys_count_mail_send where count_time >'2015-03-23 00:00:00' group by task_id;

group by查询语句中显示count(*)为0的结果

最近遇到了一个sql查询,需要统计每个用户的订单量多少,降序挨个显示出来 1:用户表user_info  user_id    user_name   001             张三...

count(字段)不统计null值

在对有null值的字段进行count时,发现count(1)与count(字段)得到的记录不一样。最后在ITPUB上朋友们的帮助下,解决了。原帖地址:http://www.itpub.net/thre...
  • lwei_998
  • lwei_998
  • 2011年01月02日 19:54
  • 15140

count(字段)不统计null值

在对有null值的字段进行count时,发现count(1)与count(字段)得到的记录不一样。 最后在ITPUB上朋友们的帮助下,解决了。 原帖地址:http://www.itpub.net/...

COUNT(*)与COUNT(某个字段)的区别,及count(null)和count(distinct 某字段)的用法

由于Oracle在count()的时候,并不计算null(空值)部分,所以和空值结合起来进行统计的时候还是有一些意思。        count这个函数应用的太频繁,有必要深究一番。         ...

SQL - SELECT COUNT用法

COUNT() 函数返回匹配指定条件的行数。   语法   SQL COUNT(column_name) 语法   COUNT(column_name) 函数返回指定列的值的数目(N...
  • kalision
  • kalision
  • 2012年07月12日 10:23
  • 22478

SpringBoot 相关的注意点

1,SpringBoot pom.xml文件中默认有两个模块: spring-boot-starter:核心模块,包括自动配置支持,日志和YAML; spring-boot-starter-test:...

【操作系统】线程间实现同步的方式

同步与互斥的区别与联系很多人不知道同步和互斥有什么区别(包括以前的我)。其实同步和互斥也是有很大联系的: 互斥:是指散布在不同进程(线程)之间的若干程序片断,当某个进程(线程)运行其中一个程序片段时,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于使用count(X) 函数的说明(附加:关于null的说明以及和0的区别)
举报原因:
原因补充:

(最多只允许输入30个字)