sql - SQL Server 2008 中的 COUNT (DISTINCT column_name) 与 COUNT (column_name) 之间存在差异吗?

标签 sql sql-server tsql sql-server-2008

我遇到了一个让我抓狂的问题。 运行下面的查询时,我得到的计数为 233,769

 SELECT COUNT(distinct  Member_List_Link.UserID)  
 FROM Member_List_Link  with (nolock)   
 INNER JOIN MasterMembers with (nolock)  
     ON Member_List_Link.UserID = MasterMembers.UserID   
  WHERE MasterMembers.Active = 1 And
        Member_List_Link.GroupID = 5 AND 
        MasterMembers.ValidUsers = 1 AND 
        Member_List_Link.Status = 1

但是,如果我运行相同的查询但没有不同的关键字,我得到的计数为233,748

 SELECT COUNT(Member_List_Link.UserID)  
 FROM Member_List_Link  with (nolock)   
 INNER JOIN MasterMembers with (nolock)
   ON Member_List_Link.UserID = MasterMembers.UserID   
 WHERE MasterMembers.Active = 1 And Member_List_Link.GroupID = 5 
  AND MasterMembers.ValidUsers = 1 AND Member_List_Link.Status = 1

为了测试,我重新创建了所有表并将它们放入临时表中并再次运行查询:

  SELECT COUNT(distinct  #Temp_Member_List_Link.UserID)  
  FROM #Temp_Member_List_Link  with (nolock)   
  INNER JOIN #Temp_MasterMembers with (nolock)
    ON #Temp_Member_List_Link.UserID = #Temp_MasterMembers.UserID   
  WHERE #Temp_MasterMembers.Active = 1 And 
        #Temp_Member_List_Link.GroupID = 5 AND 
        #Temp_MasterMembers.ValidUsers = 1 AND 
        #Temp_Member_List_Link.Status = 1

并且没有不同的关键字

  SELECT COUNT(#Temp_Member_List_Link.UserID)  
  FROM #Temp_Member_List_Link  with (nolock)   
  INNER JOIN #Temp_MasterMembers with (nolock)
    ON #Temp_Member_List_Link.UserID = #Temp_MasterMembers.UserID   
  WHERE #Temp_MasterMembers.Active = 1 And 
        #Temp_Member_List_Link.GroupID = 5 AND 
        #Temp_MasterMembers.ValidUsers = 1 AND 
        #Temp_Member_List_Link.Status = 1

顺便说一句,我通过简单地运行 (select * from Member_List_Link into #temp...) 重新创建了临时表

现在,当我检查这些临时表的 COUNT(列)与 COUNT(不同列)之间的差异时,我没有看到任何差异!

那为什么会和原来的表有出入呢?

我正在运行 SQL Server 2008(开发版)。

更新 - 包括统计资料

PhysicalOp 列仅用于第一个查询(没有不同)

NULL
Compute Scalar
Stream Aggregate
Clustered Index Seek

PhysicalOp 列仅用于第一个查询(具有不同)

NULL
Compute Scalar
Stream Aggregate
Parallelism
Stream Aggregate
Hash Match
Hash Match
Bitmap
Parallelism
Index Seek
Parallelism
Clustered Index Scan

第一个查询的行和执行(没有不同)

1   1
0   0
1   1
1   1

第二个查询的行和执行(具有不同)

Rows    Executes
1   1
0   0
1   1
16  1
16  16
233767  16
233767  16
281901  16
281901  16
281901  16
234787  16
234787  16

将 OPTION(MAXDOP 1) 添加到第二个查询(具有不同)

Rows Executes

1           1
0           0
1           1
233767          1
233767          1
281901          1
548396          1

以及由此产生的PhysicalOp

NULL
Compute Scalar
Stream Aggregate
Hash Match
Hash Match
Index Seek
Clustered Index Scan

最佳答案

来自 http://msdn.microsoft.com/en-us/library/ms187373.aspx NOLOCK 相当于 READUNCOMMITTED。有关详细信息,请参阅本主题后面的 READUNCOMMITTED。

如果行是事务的主题,READUNCOMMITED 将读取行两次 - 因为当事务正在进行时,前滚行和回滚行都存在于数据库中。

默认情况下,所有查询均已提交读取,其中不包括未提交的行

当您插入临时表时,选择将只给您提交的行 - 我相信这涵盖了您试图解释的所有症状

关于sql - SQL Server 2008 中的 COUNT (DISTINCT column_name) 与 COUNT (column_name) 之间存在差异吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7613679/

相关文章:

c# - c# 中的 SQL Server Binary(16)

c# - 更改 SqlConnection 字符串并在运行时调用 SqlConnectionStringBuilder

mysql - 使用 SQL 进行嵌套案例查询时出错

sql - 如何在数据库项目中打印 SQLCMD 变量?

mysql - 找不到简单的 sql 列

php - 试图删除数据库中的条目,收到 sql 错误但无法解决

php查询选择mysql到表网格的列

mysql - 查找特定日期按类别计数的百分比

sql-server - 如何在 SQL Server 2008 中使用 TO_CHAR 函数功能

sql - 选择 XML 节点作为行