导读:本期聚焦于小伙伴创作的《SQL中如何处理累计去重计数distinct count over window》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL中如何处理累计去重计数distinct count over window》有用,将其分享出去将是对创作者最好的鼓励。

在SQL的实际使用场景中,累计去重计数是一类很常见的需求,比如统计截至每天新增的不重复用户数、累计不重复的商品访问量等。但标准的SQL语法中,count(distinct 字段) over(partition by ... order by ...)是不被支持的,直接这么写会返回语法错误,因此需要用其他方式实现相同的效果。

通用实现方案:子查询+条件判断

最通用的思路是先给每一行的目标字段标记是否为首次出现,再对标记做累计求和,这样就能得到累计去重计数。核心逻辑是先通过子查询找到每个值第一次出现的行,再按排序规则累计统计这些首次出现的行数。

示例表结构如下,存储了用户每天的访问记录:

idvisit_dateuser_id
12024-01-011001
22024-01-011002
32024-01-021001
42024-01-021003
52024-01-031002

实现累计去重用户数的SQL代码如下:

-- 统计截至每天的累计去重用户数
SELECT
  visit_date,
  user_id,
  -- 对首次出现的用户标记求和,得到累计去重计数
  SUM(is_first_visit) OVER(ORDER BY visit_date) AS cumulative_distinct_user_count
FROM (
  SELECT
    visit_date,
    user_id,
    -- 判断当前用户是否是第一次出现,是则标记为1,否则为0
    CASE 
      WHEN ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY visit_date) = 1 THEN 1 
      ELSE 0 
    END AS is_first_visit
  FROM visit_log
) t
ORDER BY visit_date;

这段代码的执行逻辑是,内层查询先按用户分组按日期排序,给每个用户第一次出现的访问记录打上1的标记,其余记录打0,外层查询再按日期排序对这些标记做累计求和,最终得到的就是截至每一天的累计去重用户数。

数据库特定函数实现

部分数据库提供了原生的支持累计去重计数的函数,使用起来更简洁。

PostgreSQL / Snowflake

这两个数据库支持使用count(distinct 字段) over(... rows between unbounded preceding and current row)的写法,不过需要注意窗口范围要指定为从开头到当前行,示例代码如下:

SELECT
  visit_date,
  user_id,
  COUNT(DISTINCT user_id) OVER(ORDER BY visit_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_distinct_user_count
FROM visit_log
ORDER BY visit_date;

BigQuery

BigQuery可以使用APPROX_COUNT_DISTINCT配合窗口函数实现近似的累计去重计数,适合数据量极大的场景,示例代码如下:

SELECT
  visit_date,
  user_id,
  APPROX_COUNT_DISTINCT(user_id) OVER(ORDER BY visit_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_distinct_user_count
FROM visit_log
ORDER BY visit_date;

不同方案的选择建议

如果是跨数据库的场景,优先选择子查询+条件判断的通用方案,兼容性最好;如果是特定数据库的环境,可以使用对应的原生函数,代码更简洁。如果数据量极大且可以接受近似结果,BigQuery的近似计数方案效率更高。需要注意的是,通用方案在数据量极大时可能会有性能问题,因为需要对目标字段做分组排序,实际使用时可以根据数据量加合适的索引优化。

SQL累计去重计数distinct_count_over_window窗口函数数据分析修改时间:2026-06-08 22:12:22

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。