COUNT (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics Platform System (PDW)Microsoft Fabric 中的 SQL 分析终结点Microsoft Fabric 中的仓库

此函数返回组中找到的项数量。 COUNT 的操作与 COUNT_BIG 函数类似。 这些函数区别只在于其返回的值的数据类型。 COUNT 始终返回“int”数据类型值。 COUNT_BIG 始终返回“bigint”数据类型值。

Transact-SQL 语法约定

语法

聚合函数语法

COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )

分析函数语法

COUNT ( [ ALL ]  { expression | * } ) OVER ( [ <partition_by_clause> ] )

注意

若要查看 SQL Server 2014 (12.x) 及更早版本的 Transact-SQL 语法,请参阅早期版本文档

参数

ALL

向所有值应用此聚合函数。 ALL 充当默认值。

DISTINCT

指定 COUNT 返回唯一非 Null 值的数量。

expression

任意类型(“image”、“ntext”或“text”除外)的表达式COUNT 不支持表达式中的聚合函数或子查询。

*

指定 COUNT 应对所有行计数,以确定要返回的总表行计数。 COUNT(*) 不采用任何参数,也不支持使用 DISTINCT。 COUNT(*) 不需要“expression”参数,因为根据定义,该函数不使用有关任何特定列的信息。 COUNT(*) 返回指定表中的行数,但保留副本行。 它对各行分别计数。 包括包含空值的行。

OVER ( [ partition_by_clause ] [ order_by_clause ] [ ROW_or_RANGE_clause ] )

“partition_by_clause”FROM 子句生成的结果集划分为要应用 COUNT 函数的分区。 如果未指定,则此函数将查询结果集的所有行视为单个组。 “order_by_clause”确定操作的逻辑顺序。 有关详细信息,请参阅 OVER 子句 (Transact-SQL)

返回类型

  • ANSI_WARNINGSON 时,int NOT NULL,但除非包装在 ISNULL 中,否则 SQL Server 始终会在元数据中将 COUNT 表达式视为 int NULL

  • ANSI_WARNINGSOFF 时,int NULL。

备注

  • COUNT(*)(不带 GROUP BY)在结果集中返回基数(行数)。 其中包括由所有 NULL 值和重复项组成的行。
  • COUNT(*)(带 GROUP BY)返回每组中的行数。 其中包括 NULL 值和重复项。
  • COUNT(ALL <expression>) 计算组中每行的 expression,然后返回非 null 值的数量。
  • COUNT(DISTINCT *expression*) 计算组中每行的 expression,然后返回唯一非 null 值的数量。

COUNT 不与 OVER 和 ORDER BY 子句配合使用时为确定性函数。 与 OVER 和 ORDER BY 子句一同指定时,它具有不确定性。 有关详细信息,请参阅确定性函数和不确定性函数

ARITHABORTANSI_WARNINGS

如果 COUNT 具有的返回值超过 int 的最大值(即 231-1 或 2,147,483,647),则 COUNT 函数将因整数溢出而失败。 当 COUNT 溢出,ARITHABORTANSI_WARNINGS 选项两者皆为 OFF 时,COUNT 将返回 NULL。 否则,当 ARITHABORTANSI_WARNINGSON 时,查询将中止,并引发算术溢出错误 Msg 8115, Level 16, State 2; Arithmetic overflow error converting expression to data type int.。 若要正确处理这些大型结果,请改用 COUNT_BIG,这将返回 bigint。

ARITHABORTANSI_WARNINGS 皆为 ON 时,可以安全地将 COUNT 调用站点包装在 ISNULL( <count-expr>, 0 ) 中,以将表达式的类型强制转换为 int NOT NULL 而不是 int NULL。 将 COUNT 包装在 ISNULL 内意味着任何溢出错误都将以无提示方式抑制,应考虑此问题以提高正确性。

示例

A. 使用 COUNT 和 DISTINCT

此示例返回 Adventure Works Cycles 员工可以保存的不同的标题数。

SELECT COUNT(DISTINCT Title)
FROM HumanResources.Employee;
GO

下面是结果集:

-----------
67
  
(1 row(s) affected)

B. 使用 COUNT(*)

此示例返回 Adventure Works Cycles 员工的总数。

SELECT COUNT(*)
FROM HumanResources.Employee;
GO

下面是结果集。

-----------
290
  
(1 row(s) affected)

C. 将 COUNT(*) 与其他聚合函数配合使用

此示例演示 COUNT(*)SELECT 列表中的其他聚合函数配合使用。 该示例使用 AdventureWorks2022 数据库。

SELECT COUNT(*), AVG(Bonus)
FROM Sales.SalesPerson
WHERE SalesQuota > 25000;
GO

下面是结果集。

----------- ---------------------
14            3472.1428
  
(1 row(s) affected)

D. 使用 OVER 子句

此示例将 MINMAXAVGCOUNT 函数与 OVER 子句配合使用,以返回 AdventureWorks2022 数据库 HumanResources.Department 表中每个部门的聚合值。

SELECT DISTINCT Name
    , MIN(Rate) OVER (PARTITION BY edh.DepartmentID) AS MinSalary
    , MAX(Rate) OVER (PARTITION BY edh.DepartmentID) AS MaxSalary
    , AVG(Rate) OVER (PARTITION BY edh.DepartmentID) AS AvgSalary
    , COUNT(edh.BusinessEntityID) OVER (PARTITION BY edh.DepartmentID) AS EmployeesPerDept
FROM HumanResources.EmployeePayHistory AS eph
JOIN HumanResources.EmployeeDepartmentHistory AS edh
    ON eph.BusinessEntityID = edh.BusinessEntityID
JOIN HumanResources.Department AS d
ON d.DepartmentID = edh.DepartmentID
WHERE edh.EndDate IS NULL
ORDER BY Name;

下面是结果集。

Name                          MinSalary             MaxSalary             AvgSalary             EmployeesPerDept
----------------------------- --------------------- --------------------- --------------------- ----------------
Document Control              10.25                 17.7885               14.3884               5
Engineering                   32.6923               63.4615               40.1442               6
Executive                     39.06                 125.50                68.3034               4
Facilities and Maintenance    9.25                  24.0385               13.0316               7
Finance                       13.4615               43.2692               23.935                10
Human Resources               13.9423               27.1394               18.0248               6
Information Services          27.4038               50.4808               34.1586               10
Marketing                     13.4615               37.50                 18.4318               11
Production                    6.50                  84.1346               13.5537               195
Production Control            8.62                  24.5192               16.7746               8
Purchasing                    9.86                  30.00                 18.0202               14
Quality Assurance             10.5769               28.8462               15.4647               6
Research and Development      40.8654               50.4808               43.6731               4
Sales                         23.0769               72.1154               29.9719               18
Shipping and Receiving        9.00                  19.2308               10.8718               6
Tool Design                   8.62                  29.8462               23.5054               6
  
(16 row(s) affected)

示例:Azure Synapse Analytics 和 Analytics Platform System (PDW)

E. 使用 COUNT 和 DISTINCT

此示例返回特定公司的员工可以保存的不同的标题数。

USE ssawPDW;
  
SELECT COUNT(DISTINCT Title)
FROM dbo.DimEmployee;

下面是结果集。

-----------
67

F. 使用 COUNT(*)

此示例返回 dbo.DimEmployee 表中的总行数。

USE ssawPDW;
  
SELECT COUNT(*)
FROM dbo.DimEmployee;

下面是结果集。

-------------
296

G. 将 COUNT(*) 与其他聚合函数配合使用

此示例组合 COUNT(*)SELECT 列表中的其他聚合函数。 它返回年度销售配额大于 $500,000 的销售代表的人数和这些销售代表的平均销售配额。

USE ssawPDW;
  
SELECT COUNT(EmployeeKey) AS TotalCount, AVG(SalesAmountQuota) AS [Average Sales Quota]
FROM dbo.FactSalesQuota
WHERE SalesAmountQuota > 500000 AND CalendarYear = 2001;

下面是结果集。

TotalCount  Average Sales Quota
----------  -------------------
10          683800.0000

H. 将 COUNT 与 HAVING 配合使用

此示例将 COUNTHAVING 子句配合使用以返回某家公司的部门,每个部门有超过 15 位员工。

USE ssawPDW;
  
SELECT DepartmentName,
    COUNT(EmployeeKey)AS EmployeesInDept
FROM dbo.DimEmployee
GROUP BY DepartmentName
HAVING COUNT(EmployeeKey) > 15;

下面是结果集。

DepartmentName  EmployeesInDept
--------------  ---------------
Sales           18
Production      179

I. 将 COUNT 与 OVER 配合使用

此示例将 COUNTOVER 子句配合使用,返回指定的每个销售订单中包含的产品数。

USE ssawPDW;
  
SELECT DISTINCT COUNT(ProductKey) OVER(PARTITION BY SalesOrderNumber) AS ProductCount
    , SalesOrderNumber
FROM dbo.FactInternetSales
WHERE SalesOrderNumber IN (N'SO53115',N'SO55981');

下面是结果集。

ProductCount   SalesOrderID
------------   -----------------
3              SO53115
1              SO55981

另请参阅