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

BigQuery按指定日期范围、位置与类型统计去重ID实现方案

BigQuery 高效区间去重统计方案

核心思路是放弃逐天日期展开的逻辑,直接通过日期区间重叠规则匹配有效记录,同时前置清洗冗余的重复、重叠区间数据,将计算量控制在和原表相当的量级。

实现步骤

1. 前置数据清洗(可固化为视图复用)

首先处理表内两类冗余数据,减少后续计算量:

  • 完全重复的行(如id=3的三条完全一致的记录)
  • 同id+location+type维度下互相覆盖、相邻的日期区间(如id=1的两条mobile类MO地区记录,区间存在覆盖,可合并为单条连续区间)
    清洗逻辑使用窗口函数实现,不需要递归:
WITH cleaned_records AS (
  SELECT
    id,
    location,
    type,
    MIN(start_date) AS merged_start,
    MAX(end_date) AS merged_end
  FROM (
    SELECT
      *,
      -- 标记不连续的新区间分组
      COUNTIF(start_date > prev_end + 1) OVER (PARTITION BY id, location, type ORDER BY start_date) AS range_group
    FROM (
      SELECT
        id,
        location,
        type,
        start_date,
        end_date,
        -- 取同维度下上一条记录的结束日期
        LAG(end_date) OVER (PARTITION BY id, location, type ORDER BY start_date) AS prev_end
      FROM (
        -- 第一步先去除完全重复的记录
        SELECT DISTINCT id, start_date, end_date, location, type
        FROM `你的项目名.数据集名.表名`
      )
    )
  )
  GROUP BY id, location, type, range_group
)

2. 直接按日期区间重叠规则统计

两个日期区间存在重叠的判断逻辑非常简单,不需要逐天匹配:

记录的开始日期 <= 查询结束日期 且 记录的结束日期 >= 查询开始日期
只要满足该条件,就说明对应id在查询时间范围内有覆盖,直接按维度统计去重id即可。
以你给出的查询2022-01-02至2022-01-03的需求为例,完整查询代码如下:

WITH cleaned_records AS (
  -- 上述清洗逻辑,若已固化为视图可直接替换为 FROM `你的清洗后视图名`
  SELECT
    id,
    location,
    type,
    MIN(start_date) AS merged_start,
    MAX(end_date) AS merged_end
  FROM (
    SELECT
      *,
      COUNTIF(start_date > prev_end + 1) OVER (PARTITION BY id, location, type ORDER BY start_date) AS range_group
    FROM (
      SELECT
        id,
        location,
        type,
        start_date,
        end_date,
        LAG(end_date) OVER (PARTITION BY id, location, type ORDER BY start_date) AS prev_end
      FROM (
        SELECT DISTINCT id, start_date, end_date, location, type
        FROM `your_project.your_dataset.your_table`
      )
    )
  )
  GROUP BY id, location, type, range_group
)
SELECT
  location,
  type,
  COUNT(DISTINCT id) AS `count distinct ID`
FROM cleaned_records
WHERE
  -- 替换为实际查询的起止日期即可
  merged_start <= DATE('2022-01-03')
  AND merged_end >= DATE('2022-01-02')
GROUP BY location, type
ORDER BY location, type

结果验证&性能说明

  • 基于你提供的样例数据运行上述代码,返回结果和预期完全一致:
locationtypecount distinct ID
AZlaptop1
AZmobile1
CAlaptop2
CAmobile1
MOmobile1
  • 性能优势:
    • 全程无日期数组join、无逐行展开操作,所有计算为窗口聚合+简单比较运算,计算量和原表数据量持平,完全适配大数据量场景
    • 清洗逻辑可固化为视图或定期更新的物理表,查询时仅需做简单过滤即可,不需要每次全表重算

内容的提问来源于stack exchange,提问作者redditor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:42:13