You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL如何统计每个日期对应30天滚动区间内的去重活跃用户数

修正后可直接使用的SQL

WITH daily_active_users AS (
  -- 第一步:得到所有去重的<活跃日期, 组织ID>对,避免单用户单日重复计数
  SELECT DISTINCT
    DATE_TRUNC(PARSE_DATE('%Y%m%d', event_date), DAY) AS active_date,
    -- 从当前行的用户属性中取组织ID,修正原有SQL交叉连接导致的关联错误
    (SELECT value.string_value FROM UNNEST(user_properties) WHERE key = 'organization_id') AS organization_id
  FROM `[app]-project.analytics_[numbers].events_intraday_*`
  WHERE 
    event_name = 'Active Seller Event'
    -- 过滤无组织ID的无效数据
    AND (SELECT value.string_value FROM UNNEST(user_properties) WHERE key = 'organization_id') IS NOT NULL
),
all_stat_dates AS (
  -- 第二步:拿到所有需要统计的日期维度
  SELECT DISTINCT active_date AS event_date
  FROM daily_active_users
  -- 如果需要补全没有活跃记录的日期,可替换为下面的语句,替换起止日期即可
  -- SELECT date AS event_date FROM UNNEST(GENERATE_DATE_ARRAY('2021-07-01', CURRENT_DATE())) AS date
)
-- 第三步:按30天区间关联统计去重用户数
SELECT
  a.event_date,
  -- 拼接日期区间显示,调整INTERVAL数值可修改统计范围
  CONCAT(DATE_SUB(a.event_date, INTERVAL 29 DAY), ' to ', a.event_date) AS count_date_range,
  COUNT(DISTINCT b.organization_id) AS active_30_days
FROM all_stat_dates a
LEFT JOIN daily_active_users b
  ON b.active_date BETWEEN DATE_SUB(a.event_date, INTERVAL 29 DAY) AND a.event_date
GROUP BY a.event_date, count_date_range
ORDER BY a.event_date DESC

逻辑说明

  • 原有SQL的FROM子句使用了交叉连接,会导致组织ID和事件行没有关联,统计结果存在错误,上面的方案直接从当前事件行的用户属性中提取对应组织ID,保证数据关联正确
  • 如果需要统计的是「往前推30自然日+当天共31天」的范围,把SQL里的INTERVAL 29 DAY改成INTERVAL 30 DAY即可
  • 若数据量较大,可使用BigQuery原生的HLL近似去重优化性能,误差在2%以内,性能提升10倍以上,优化写法如下:
WITH daily_hll AS (
  SELECT
    DATE_TRUNC(PARSE_DATE('%Y%m%d', event_date), DAY) AS active_date,
    -- 按日预计算组织ID的HLL sketch
    HLL_COUNT.INIT((SELECT value.string_value FROM UNNEST(user_properties) WHERE key = 'organization_id'), 15) AS hll_org
  FROM `[app]-project.analytics_[numbers].events_intraday_*`
  WHERE event_name = 'Active Seller Event'
  GROUP BY active_date
)
SELECT
  active_date AS event_date,
  CONCAT(DATE_SUB(active_date, INTERVAL 29 DAY), ' to ', active_date) AS count_date_range,
  -- 用窗口函数合并近30天的HLL sketch得到去重数
  HLL_COUNT.MERGE(hll_org) OVER (ORDER BY UNIX_DATE(active_date) RANGE BETWEEN 29 PRECEDING AND CURRENT ROW) AS active_30_days
FROM daily_hll
ORDER BY active_date DESC

内容的提问来源于stack exchange,提问作者Mahmood H. Alnasser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 23:09:04