SQL 如何处理“累计去重用户数”在时间窗口内的计算-SQL

主流SQL引擎不支持COUNT(DISTINCT)直接用于窗口函数,因去重逻辑与窗口累积语义冲突;可用ARRAY_AGG+ARRAY_DISTINCT模拟累计去重,适用于中小规模数据。

为什么 COUNT(DISTINCT ...) 不能直接套窗口函数

直接写 SELECT COUNT(DISTINCT user_id) OVER (ORDER BY dt ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 会报错——主流 SQL 引擎(如 PostgreSQL、MySQL 8.0+、Spark SQL)都不支持对 COUNT(DISTINCT) 使用窗口函数。本质是去重逻辑与窗口的累积语义冲突:窗口需要逐行维护状态,而 DISTINCT 是聚合操作,不可拆分。

用 ARRAY_AGG + ARRAY_DISTINCT 模拟累计去重(PostgreSQL / Spark SQL)

适用于中小规模数据(日活 user_id 收集为数组,再去重取长度:

SELECT
  dt,
  ARRAY_LENGTH(ARRAY_DISTINCT(ARRAY_AGG(user_id) OVER (ORDER BY dt)), 1) AS cumu_unique_users
FROM events
GROUP BY dt;
  • ARRAY_AGG 必须配合 GROUP BY dt,否则同一日期多行会重复累加
  • PostgreSQL 需要 ARRAY_DISTINCT(v14+),旧版可用 ARRAY(SELECT DISTINCT unnest(...)) 替代,但性能差
  • Spark SQL 中对应函数是 size(array_distinct(collect_list(user_id))),注意 collect_list 不去重,必须套 array_distinct
  • 内存风险:若某天用户量极大(如千万级),ARRAY_AGG 可能 OOM

用自连接 + 子查询实现精确累计(通用兼容方案)

不依赖高级数组函数,所有 SQL 引擎都支持,但需注意性能和去重逻辑边界:

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » SQL 如何处理“累计去重用户数”在时间窗口内的计算-SQL
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1391+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 3995390+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1391+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 3995391+
  • 本周更新: 0+
  • 最后更新: 2026-03-16