编程BI/分析师, 数据工程师

如何正确实现根据复杂标准计算唯一用户的数量,同时考虑NULL和重复项,使用SQL中的DISTINCT,COUNT,GROUP BY结构?

用 Hintsage AI 助手通过面试

答复。

问题背景

唯一用户的报告对于分析和统计是必要的。然而,在实际数据中,常常会出现账户重复、NULL值(例如,未提供的电子邮件),并且需要考虑不同的标准(例如,按名称、电子邮件、IP的唯一性,有时是它们的组合)。

问题

一种典型错误是计算COUNT(DISTINCT user_id),而没有考虑到所需列中存在NULL或不明显的重复项(例如,一个人有不同的电子邮件,或者几行有相同的user_id和不同的状态)。复杂的带有GROUP BY的查询可能会给出错误的结果,特别是当唯一性逻辑没有被仔细考虑时。

解决方案

重要的是要结合使用DISTINCT,GROUP BY和NULL过滤。有时需要在CTE或嵌套子查询中提前准备数据,通过所需的一组特征进行分组。

代码示例:

-- 根据电子邮件和IP计算唯一用户数量,忽略NULL SELECT COUNT(*) AS unique_users FROM ( SELECT DISTINCT email, ip_address FROM users WHERE email IS NOT NULL AND ip_address IS NOT NULL ) u;

关键特性:

  • DISTINCT不计算在任何列中有NULL的行
  • 对于交叉分组,最好使用按字段组合的GROUP BY
  • 处理重复数据时,通常需要提前“清理”数据

可能的陷阱。

COUNT(DISTINCT ...)会考虑包含NULL的行吗?

不:如果DISTINCT列表中的任何列的值为NULL,则该组合被视为单独的唯一值(在SQL标准中,NULL不等于NULL)。通常先通过过滤去除NULL会更方便。


可以通过DISTINCT比较NULL与NULL吗?

在SQL中,每对NULL值被视为不同,因此在任何列中有NULL的每一行都会被视为单独的。需要通过IS NOT NULL进行过滤。


GROUP BY总是给出与DISTINCT相同的结果吗?

不:GROUP BY对每个不重复的值组合生成一行,而DISTINCT只是删除重复项。在某些情况下,结果会不同,特别是当应用聚合时。

常见错误和反模式

  • 对NULL值的不明显过滤
  • 在聚合之前未显式重复数据
  • DISTINCT与不同层次聚合的组合不当

生活中的示例

负面案例

业务分析师通过COUNT(DISTINCT user_id)生成唯一客户报告,而user_id在实际中可能为NULL或重复(例如,临时账户)。实际用户数量大于真实数量 — 报告中的指标失真。

优点:

  • 快速生成报告

缺点:

  • 由于不正确的指标导致的不当商业决策

积极案例

分析师提前清理数据,过滤NULL和显式重复项在子查询中,并使用集合操作来处理复杂的唯一标准。

优点:

  • 正确和透明的指标
  • 有效的商业决策和KPI

缺点:

  • 更复杂的查询,需要在测试数据上进行质量检查。