SQL SERVER DB中的计数功能能否接受多个值

时间:2020-06-13 16:04:55

标签: sql-server tsql group-by count ssms-2017

我正在查询SSMS中非常流行的AdventureWorks DB。 我的目标是从HumanResources.Employee中找到每个职位下的男性和女性人数。

为此,我最初的查询是

SELECT JobTitle,
COUNT(CASE WHEN Gender='M' THEN 1
ELSE 0
END) AS MALE_COUNT,
COUNT(CASE WHEN Gender='F' THEN 1
ELSE 0
END) AS FEMALE_COUNT,Gender
FROM HumanResources.Employee
GROUP BY JobTitle,Gender
ORDER BY JobTitle
GO

但是,我对上述查询的回答不正确。因此,通过如下修改,我得到了预期的结果:

SELECT JobTitle,
COUNT(CASE WHEN Gender='M' THEN 1
END) AS MALE_COUNT,
COUNT(CASE WHEN Gender='F' THEN 1
END) AS FEMALE_COUNT,Gender
FROM HumanResources.Employee
GROUP BY JobTitle,Gender
ORDER BY JobTitle
GO

很容易看出,我只是删除了两个CASE语句的“ ELSE 0”条件,但是我无法弄清楚“ 0”如何影响结果中返回的值。

有人可以向我解释这两者之间的区别吗?我也想知道COUNT函数如何取多个值,通常情况下(例如SELECT COUNT(3,3))不起作用。

2 个答案:

答案 0 :(得分:2)

您想要SUM(),而不是COUNT():后者考虑了每个非{null值(其中包括0),因此您当前的条件表达式计算所有行-相当于COUNT(*)

此外,我怀疑genderSELECT子句中不应出现GROUP BY,因为这正是您要汇总的内容

我认为您想要

SELECT 
    JobTitle,
    SUM(CASE WHEN Gender='M' THEN 1 ELSE 0 END) AS MALE_COUNT,
    SUM(CASE WHEN Gender='F' THEN 1 ELSE 0 END) AS FEMALE_COUNT
FROM HumanResources.Employee
GROUP BY JobTitle
ORDER BY JobTitle

答案 1 :(得分:1)

文档说:

COUNT(ALL表达式)计算组中每一行的表达式, 并返回非空值的数量。

在此处了解更多信息:https://docs.microsoft.com/en-us/sql/t-sql/functions/count-transact-sql?view=sql-server-ver15

因此我们可以将您的查询重写为:

SELECT 
    JobTitle,
    COUNT(CASE WHEN Gender='M' THEN 1 ELSE NULL END) AS MALE_COUNT,
    COUNT(CASE WHEN Gender='F' THEN 1 ELSE NULL END) AS FEMALE_COUNT
FROM HumanResources.Employee
GROUP BY JobTitle
ORDER BY JobTitle

关于您的查询:

第一个查询:

在Count函数内部,您有一个CASE表达式,该表达式会将'M'更改为1,将'F'更改为0。然后COUNT函数将对其进行计数操作。因为1和0都不为NULL,所以Count将返回记录总数,而不考虑'M'或'F'

第二CASE的步骤也相同。

第二个查询:

Count函数内部,您有一个CASE表达式,该表达式会将'M'更改为1,但是您没有提到如何处理其他值,因此对于非M值,将返回NULL。 。之后,Count函数将对这些记录进行计数操作并返回M的数量。(第二个查询等于我发布的查询,并且它们都具有相同的输出。但是由于可读性,我比您的查询更喜欢我的查询:-))

第二CASE的步骤也相同。

CASE表达式的文档说:

ELSE else_result_expression是否返回表达式? 比较运算的结果为TRUE。如果省略此参数 并且没有比较运算的结果为TRUE,CASE返回NULL。 else_result_expression是任何有效的表达式。的数据类型 else_result_expression和任何result_expression必须相同或 必须是隐式转换。

在此处了解更多信息:https://docs.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-sql?view=sql-server-ver15

选择计数(3,3)

这在语法上是错误的,并且会给您这样的错误,这很容易解释:

消息174,级别15,状态1,第1行计数功能需要1 论点

基于上述文档的Count函数的语法如下:

-- Aggregation Function Syntax  
COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )  

-- Analytic Function Syntax  
COUNT ( [ ALL ]  { expression | * } ) OVER ( [ <partition_by_clause> ] )