使用group by计数(属性)和计数(*)之间的差异

时间:2012-06-02 16:13:22

标签: sql

我还没有理解count(*)和以属性为参数的计数之间的区别 在这里我举一个例子:有两种关系:

project (id, name, number);
employee (ssn, name, surname);
working_on (employee_ssn,   project_id);

employee_ssn引用employee(ssn)project_id引用project(id)
主键:project(id)employee(ssn),working_on(employee_ssnproject_id)。
现在我必须找到每个项目,项目的ID,名称和工作人员的数量 这是一个正确的解决方案(在本书中找到):

select id, name, count (*)
from working_on join project on id=project_id
group by name, id

我已经理解为什么这个解决方案有效,不应该count (*)计算所有元组?为什么这样才能获得确切的员工数量? 我写了这个解决方案:

select id, name, count (employee_ssn)
from working_on join project on id=project_id
group by name, id

解决方案是否相同?
一般情况下,使用count (*)count(attribute)会有所不同吗?你能提供一个这两个语法产生不同结果的例子吗?

4 个答案:

答案 0 :(得分:4)

来自documentation

  

COUNT(表达式)

     

返回行中 expr 的非NULL值的计数   通过SELECT声明检索。


  

COUNT(*)有些不同,因为它返回的计数   检索的行数,无论它们是否包含NULL值。

换句话说:

COUNT(expr)将返回 expr 没有NULL值的行数。

COUNT(*)将返回返回的总行数。

您是否使用GROUP BY条款无关紧要。

答案 1 :(得分:3)

count(*)将计为NULL,而count(attribute)则不会。因此,当列中包含NULL值时,唯一的区别就会出现

答案 2 :(得分:1)

到目前为止,我发现了两个不同之处 -

  1. 如上面提到的那样,count(col)不计算空值,而count(*)则计数。

  2. 在联接查询中,它的行为有所不同。

  3. 考虑我需要加入员工和部门表的情况,我需要找到每个部门的员工数量。

    2.A。

    SELECT     DPT.ID 
    ,          COUNT(*) EMP_COUNT
    FROM       DEPARTMENT DPT
    INNER JOIN EMPLOYEE E
    ON         DPT.ID = E.DEPARTMENT_ID
    GROUP BY   DPT.ID;
    

    在上面的查询中,它不会返回employee table count = 0的那些记录。

    2.B。

    SELECT     DPT.ID 
    ,          COUNT(E.DEPARTMENT_ID) EMP_COUNT
    FROM       DEPARTMENT DPT
    INNER JOIN EMPLOYEE E
    ON         DPT.ID = E.DEPARTMENT_ID
    GROUP BY   DPT.ID;
    

    如果使用count(E.DEPARTMENT_ID)而不是count(*),这次即使员工表计数= 0,它也会给出记录。

    2.C。

    SELECT     DPT.ID 
    ,          COUNT(DPT.ID) EMP_COUNT
    FROM       DEPARTMENT DPT
    INNER JOIN EMPLOYEE E
    ON         DPT.ID = E.DEPARTMENT_ID
    GROUP BY   DPT.ID;
    

    这是有趣的部分,当你使用COUNT(DPT.ID),因为DPT.ID是部门的列,这里再次记录不会考虑员工表计数= 0的地方。

答案 3 :(得分:0)

正如其他人所说,COUNT(*) 将计算检索到的总行数,但是,COUNT(attribute_name) 将仅计算非空值的数量。 实际上,它们都计算非空值的数量,但是,由于在关系数据库中不应该有行元组将其所有值都设为 NULL(它应该有一个不能为 NULL 的主键),{{ 1}} 将始终返回表中的总行数 -relation- 构成,主键列的值数 -attribute-