解释DISTINCT COUNT的行为(*)

时间:2014-04-20 03:51:19

标签: sql

在回答另一个问题时,运行了一个查询,给了我意想不到的结果。将COUNT和DISTINCT组合为COUNT(DISTINCT字段)以获取字段中的非空不同值的数量是正常的。

我还尝试过DISTINCT COUNT(字段),希望能够向我显示"计数数量"这基本上总是1.但那是它的作用。

CREATE TABLE Bob (id INT)
INSERT INTO Bob VALUES (0),(0),(1),(NULL)

SELECT COUNT(DISTINCT id) FROM Bob 
--Result: 2
SELECT COUNT(id) FROM Bob          
--Result: 3
SELECT DISTINCT COUNT(id) FROM Bob
--Result: 3
SELECT COUNT(*) FROM Bob
--Result: 4
SELECT DISTINCT COUNT(*) FROM Bob
--Result: 4

相反,当使用这种方式时,看起来好像查询引擎简单地忽略了DISTINCT。我对SQL Server,MySQL,Oracle,PostGreSQL和SQLite进行了测试,行为是一样的。

这里SQL Server fiddle你很好奇。

您能否根据ANSI标准或其他一些历史惯例来解释这种行为?或者也许我原来预期的行为在某种程度上是有缺陷的。

2 个答案:

答案 0 :(得分:3)

查询实际上是按预期工作的,但一开始理解原因有点棘手。

查看正在发生的事情的最佳方法是检查查询执行计划。

首先选择Select Distinct Count。读取计划,从右到左,您应该看到一个表扫描,其中4行传递给Stream Aggregate。从那里,你有一行传递给Compute Scalar,它的值为4,因此SQL输出4。

现在,查看Select Count(非常ID)。再次从右到左,您应该看到表格扫描,其中4行传递到排序。在SQL可以计算它们对它们进行排序所需的不同行之前,然后将2行传递给Stream Aggregate,它会传递2的计数。

答案 1 :(得分:3)

first row我的意思是:

SELECT COUNT(DISTINCT id) FROM Bob

这意味着我们获得COUNT OF DISTINCT IDs此示例中的0,0,1,null它返回COUNT OF 0,1,null,但null无法计算,因为它返回2 }

Second row中的

SELECT COUNT(id) FROM Bob  

在此示例中COUNT OF IDs表示0,0,1,null,但正如我所说null无法计算并返回3

third row中的

SELECT DISTINCT COUNT(id) FROM Bob

这意味着DISTINCT COUNT OF IDs,但这里的意思是COUNT OF IDs,如果我们使用Group by并且计数得到了很多结果,那么它会返回COUNTs的不同,并在此处返回COUNT OF IDs我的意思是3,此 SQL Fiddle 可以为您提供更好的线索。

fourth row中的

SELECT COUNT(*) FROM Bob

表示COUNT OF ROWS,此处我们有4行。

fifth row中的

SELECT DISTINCT COUNT(*) FROM Bob

表示DISTINCT COUNT OF the ROWS,但在Group by之外,它会返回一个值,并且该值也是不同的,它会在此处返回4