COUNT(*) 和 COUNT(*) OVER() 有什么区别

Dav*_*man 13 sql-server t-sql window-functions

以下面的代码示例为例:

SELECT MaritalStatus,
       COUNT(*) AS CountResult
       COUNT(*) OVER() AS CountOverResult
       FROM (schema).(table)
       GROUP BY Marital Status
Run Code Online (Sandbox Code Playgroud)

COUNT(*) 返回所有行忽略空值对吗?

有什么作用COUNT(*) OVER()

这个问题是在练习考试中出现的,所以我没有要查询的数据。我一直在使用 Adventure Works 和这个网站http://www.sqlishard.com/Exercise来练习。

如果我输入一个查询

SELECT ID, COUNT(*) AS 'COUNT(*)' , COUNT(*) OVER() AS 'COUNT(*) OVER()'
FROM Customers
GROUP BY ID
Run Code Online (Sandbox Code Playgroud)

进入练习站点,我得到 3794 行返回,其中一Count(*)列是 1,一Count(*) Over()列是总行数。我不明白这个模式(对不起)所以我来到了这里。

Mar*_*ith 19

COUNT(*) 返回所有行,忽略空值,对吗?

我不确定你在这里“忽略空值”是什么意思。它返回行数,而不考虑任何NULLs

SELECT COUNT(*)       
FROM (VALUES (CAST(NULL AS INT)),
             (CAST(NULL AS INT))) V(C)
Run Code Online (Sandbox Code Playgroud)

返回2

将上述查询更改为与表达式一起使用时COUNT(C)将返回0,而COUNT不是*NOT NULL计算该表达式的值。

假设您问题中的表具有以下源数据

+---------+---------------+
|  Name   | MaritalStatus |
+---------+---------------+
| Albert  | Single        |
| Bob     | Single        |
| Charles | Single        |
| David   | Single        |
| Edward  | Married       |
| Fred    | Married       |
| George  | NULL          |
+---------+---------------+
Run Code Online (Sandbox Code Playgroud)

查询

SELECT MaritalStatus,
       COUNT(*) AS CountResult
FROM   T
GROUP  BY MaritalStatus 
Run Code Online (Sandbox Code Playgroud)

退货

+---------------+-------------+
| MaritalStatus | CountResult |
+---------------+-------------+
| Single        |           4 |
| Married       |           2 |
| NULL          |           1 |
+---------------+-------------+
Run Code Online (Sandbox Code Playgroud)

希望该结果与原始数据的关系很明显。

有什么作用COUNT(*) OVER()

将其添加到SELECT前一个查询的列表中会产生

+---------------+-------------+-----------------+
| MaritalStatus | CountResult | CountOverResult |
+---------------+-------------+-----------------+
| Single        |           4 |               3 |
| Married       |           2 |               3 |
| NULL          |           1 |               3 |
+---------------+-------------+-----------------+
Run Code Online (Sandbox Code Playgroud)

请注意,结果集有 3 行,CountOverResult 为 3。这不是巧合。

这样做的原因是因为它对GROUP BY.

COUNT(*) OVER ()是一个窗口聚合。没有 any PARTITION BYorORDER BY子句意味着它操作的窗口是整个结果集。

在您问题中的查询的情况下, 的值与基表中存在CountOverResult的不同MaritalStatus值的数量相同,因为分组结果中的每个值都有一行。