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

如何在BigQuery中生成域间独立访客差异透视表?

解决BigQuery中动态域名透视表(域间独立访客差异)的方案

这个需求确实需要结合数组聚合和动态SQL来应对200个域名的场景,下面是完整的可执行方案,完美匹配你要的结果:

完整代码

首先替换代码中的your-project.your-dataset.your-table为你实际的表路径:

DECLARE cols STRING;

-- 动态生成所有域名对应的透视列语句
SET cols = (
  SELECT STRING_AGG(DISTINCT CONCAT('MAX(IF(domain_col = "', d, '", value, 0)) AS `', d, '`'), ', ')
  FROM (SELECT DISTINCT Domain AS d FROM `your-project.your-dataset.your-table`)
);

-- 执行动态透视查询
EXECUTE IMMEDIATE '''
WITH user_domains AS (
  -- 第一步:聚合每个用户访问的所有域名到数组中
  SELECT
    UserID,
    ARRAY_AGG(DISTINCT Domain) AS domains
  FROM
    `your-project.your-dataset.your-table`
  GROUP BY
    UserID
),
all_domains AS (
  -- 第二步:获取所有唯一域名,用于生成行和列的全组合
  SELECT DISTINCT Domain AS d FROM `your-project.your-dataset.your-table`
),
domain_comparison AS (
  -- 第三步:计算每个域名(行)与其他域名(列)的独立访客标记
  SELECT
    d1.d AS domain_row,
    d2.d AS domain_col,
    -- 判断是否存在「访问了行域名但未访问列域名」的用户,存在则标1,否则0
    IF(EXISTS(
      SELECT 1 FROM user_domains ud
      WHERE d1.d IN UNNEST(ud.domains)
        AND d2.d NOT IN UNNEST(ud.domains)
    ), 1, 0) AS value
  FROM
    all_domains d1
  CROSS JOIN
    all_domains d2
  WHERE d1.d != d2.d -- 先处理不同域名的组合
  UNION ALL
  -- 补充域名自身对比的情况,固定为0
  SELECT
    d AS domain_row,
    d AS domain_col,
    0 AS value
  FROM all_domains
)
-- 第四步:透视成目标格式
SELECT domain_row AS ''', cols, '''
FROM domain_comparison
GROUP BY domain_row
ORDER BY domain_row
''';

代码逻辑拆解

  1. user_domains CTE:把每个用户访问过的域名聚合成一个数组,这样后续可以快速判断某个用户是否同时访问了两个域名,避免多次关联表带来的性能问题。
  2. all_domains CTE:提取所有唯一的域名,用来生成行和列的全量组合(笛卡尔积),确保每个域名都能作为行和列出现。
  3. domain_comparison CTE:核心逻辑部分,对每一对域名组合(d1作为行,d2作为列),检查是否存在用户访问了d1但没访问d2:
    • 如果存在这样的用户,标记为1;
    • 如果所有访问d1的用户都访问了d2,标记为0;
    • 域名自身对比的情况直接设为0。
  4. 动态透视处理:因为域名有200个,手动写列不现实,所以用DECLARE和EXECUTE IMMEDIATE动态生成透视列的语句,自动适配所有域名。

示例数据验证

用你提供的示例数据测试时,会得到完全符合预期的结果:

domain_rowABC
A011
B000
C000

解释一下结果:

  • 行A:存在用户3访问了A但没访问B和C,所以B、C列标1;
  • 行B:所有访问B的用户(1、2)都同时访问了A和C,所以A、C列标0;
  • 行C:所有访问C的用户(1、2)都同时访问了A和B,所以A、B列标0。

注意事项

  • 如果你的域名包含特殊字符(比如空格、引号),需要调整cols变量中的转义逻辑,用反引号`包裹域名会更稳妥;
  • 对于超大数据集,可以考虑对user_domains的数组做预聚合优化,提升查询性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:18:39