【问题标题】:Discrepancy with "count(distinct(field))" statement in SQL querySQL 查询中与“count(distinct(field))”语句的差异
【发布时间】:2013-01-14 06:16:07
【问题描述】:

我正在 SQL Server 中运行查询,以按澳大利亚州统计我们数据库中存在的唯一电子邮件地址的数量。但是,当我尝试核对这些数字以确保它们正确时,我注意到了一个差异,这让我认为我的查询不正确。以下是我用来协调数字和实际结果的查询:

/** Count the total number of active members (status=1) since last night **/
SELECT count(distinct(email)) Total FROM [member] WHERE status = 1 
AND (created_datetime <= '2013-01-11' OR created_datetime IS NULL)
/** RESULT: 8958 **/

/** Count the number of active members (status=1) who live in Victoria since last night **/
SELECT count(distinct(email)) Total FROM [member] WHERE status = 1 
AND (created_datetime <= '2013-01-11' OR created_datetime IS NULL)
AND [state] = 'vic'
/** RESULT: 7545 **/

/** Count the number of active members (status=1) who don't live in Victoria since last night **/
SELECT count(distinct(email)) Total FROM [member] WHERE status = 1 
AND (created_datetime <= '2013-01-11' OR created_datetime IS NULL)
AND [state] <> 'vic'
/** RESULT:1446 **/

/** Add the two results to see how they compare to the total **/
SELECT 7545+1446
/** RESULT:8991 **/

您会注意到不同电子邮件的总数为 8958 封,但如果您将居住在维多利亚州的电子邮件和未居住在维多利亚州的电子邮件相加,则数字为 8991,这是不同的。我是否错误地使用了 count distinct 功能?

【问题讨论】:

  • &lt;= '2013-01-10 23:59:59' - 所以您不想包含一天的最后一秒发生的任何事情?几乎总是更好(使用日期查询)为期间使用专有端点 - 例如&lt; '20130111'.
  • 好点。我已经更新了查询,我将在上面编辑我的问题

标签: sql sql-server count distinct


【解决方案1】:

where 子句中的 created_datetime 不同。在第一个查询中是

WHERE status = 1 
AND (created_datetime <= '2013-01-10 23:59:59' OR created_datetime IS NULL)

其他两个查询是

WHERE status = 1 
AND (created_datetime <= '2013-01-31 00:00:00' OR created_datetime IS NULL)
AND [state] <> 'vic'

拉吉

【讨论】:

  • 好地方。我已经更新了查询并修改了我的问题。但是结果是一样的(主要是因为我写问题时两个日期都在将来)
【解决方案2】:

在@Raj 和@MarkD 提供的答案之上,我想添加另一个观察结果。
不应该

OR created_datetime IS NULL

只出现在其中一个语句中而不是两个语句中?如果两者都存在,则会出现重复,并且“总”查询的结果永远不会与单个查询的总和匹配。

【讨论】:

  • @oragecrush 对我来说是正确的,因为在所有查询中我们都得到了 created_datetime = NULL 的重复
  • 好的,所以我尝试再次运行测试两次 - 在一次测试中从“谁住在维多利亚”查询中删除“OR created_datetime IS NULL”,并从“谁没有”中删除相同的语句住在维多利亚”第二次查询,不幸的是,数字仍然没有加起来。
  • 有一点需要注意...如果我从所有查询中删除 OR created_datetime IS NULL 并运行测试,数字就会加起来。但我想这对我来说没什么用,因为它忽略了我的大量用户
  • 可能有重复的电子邮件?如果为来自“vic”的成员输入了相同的电子邮件,而为另一个州输入了相同的电子邮件,则必然会有重复。如果练习的目的是将个人计数与总数相比较,为什么不删除distinct 并计算整个电子邮件列表?那应该给你一个匹配。
  • 理论上任何重复的成员都应该处于相同的状态,但我不能保证这一点。肯定有重复的电子邮件。练习的要点是编写一份报告,显示唯一成员的数量,然后所有细分(按州、然后是性别、然后是年龄)都应该与这个总数相符。但目前他们没有,所以我编译了上面的示例只是为了在网络上演示这一点。我有点不知所措
【解决方案3】:

您正在计算 不同 封电子邮件。如果来自 Victoria 的用户的电子邮件与其他地方的用户的电子邮件相同,则这些电子邮件将计为 1。

当分别计算维多利亚和非维多利亚的电子邮件时,在每种情况下,两者都会再次计为 1,给您总共 2(如果您敢将它们相加的话),这将是您现在所遇到的差异。

【讨论】:

  • 我认为这是一个非常有效的观点 Andriy。那么有什么方法可以显示以下内容:所有用户的总数(来自所有州,或没有状态的用户),然后是每个州的用户细分(没有状态的用户有单独的列)?总数应与细分的总和一致
  • 也许你想要SELECT state, COUNT(*) FROM member GROUP BY state这样的东西?
【解决方案4】:

您的[State]s 的余额可能是NULL 正如 Raj 指出的那样,您查询中的 DATETIME 不同。

SELECT count(distinct(email)) Total FROM [member] WHERE status = 1 
AND (created_datetime <= '2013-01-31 00:00:00' OR created_datetime IS NULL)
AND [state] IS NULL

【讨论】:

  • 如果我运行 SELECT count(distinct(email)) Total FROM [Staging-vPowerClub].[dbo].[member] WHERE AND [state] IS NULL 它会返回 0 个结果,所以所有条目都有一个关联的 [state]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
相关资源
最近更新 更多