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

BigQuery中两周Top销售供应商数据对比及变化率计算问题咨询

解决BigQuery中前后周Top供应商关联及销售额变化计算问题

嘿,我帮你梳理下问题:你之前的查询用逗号拼接两个子查询,产生了笛卡尔积——也就是每个当前周的供应商都和上周所有供应商配对了一遍,这就是结果不符合预期的核心原因。我们需要用正确的关联方式匹配相同供应商的数据,同时动态处理日期,还要搞定变化百分比的计算。

下面是完整的解决方案,分步骤解释:

1. 先动态匹配每周的前一周日期

硬编码日期(比如2021-11-14)太不灵活,我们可以用LAG()函数自动为每个周日期关联它的前一周:

WITH weekly_dates AS (
  SELECT 
    date AS current_date,
    -- 按日期排序,取上一个周的日期
    LAG(date) OVER (ORDER BY date) AS previous_date
  FROM (SELECT DISTINCT date FROM `table.top20_vendor`)
)

这个CTE会输出所有周的日期,以及对应的前一周日期,后续新增周数据也能自动适配。

2. 关联当前周和上周的供应商数据

用LEFT JOIN按供应商名称+上周日期来关联,这样新上榜的供应商(上周没有的)会保留,但上周的字段会是Null:

, current_prev_vendors AS (
  SELECT
    curr.date AS `date(week)`,
    curr.vendor_name,
    curr.value,
    prev.date AS previous_date,
    prev.vendor_name AS previous_top_vendors,
    prev.value AS previous_value
  FROM `table.top20_vendor` curr
  -- 关联到我们刚才生成的周日期映射
  JOIN weekly_dates wd ON curr.date = wd.current_date
  -- 左连接上周的同供应商数据
  LEFT JOIN `table.top20_vendor` prev 
    ON curr.vendor_name = prev.vendor_name 
    AND prev.date = wd.previous_date
  -- 只取最新一周的数据,如果要所有周的对比可以去掉这个条件
  WHERE wd.current_date = (SELECT MAX(date) FROM `table.top20_vendor`)
)

这里的LEFT JOIN是关键,它确保当前周的供应商即使上周没上榜,也会出现在结果里,而不是被过滤掉。

3. 计算销售额变化百分比

最后处理change列:如果上周有该供应商的数据,就计算变化率,按照你给的示例格式(正数加%,负数加-);如果是新供应商,直接显示Null。

完整SQL代码

WITH weekly_dates AS (
  SELECT 
    date AS current_date,
    LAG(date) OVER (ORDER BY date) AS previous_date
  FROM (SELECT DISTINCT date FROM `table.top20_vendor`)
),
current_prev_vendors AS (
  SELECT
    curr.date AS `date(week)`,
    curr.vendor_name,
    curr.value,
    prev.date AS previous_date,
    prev.vendor_name AS previous_top_vendors,
    prev.value AS previous_value
  FROM `table.top20_vendor` curr
  JOIN weekly_dates wd ON curr.date = wd.current_date
  LEFT JOIN `table.top20_vendor` prev 
    ON curr.vendor_name = prev.vendor_name 
    AND prev.date = wd.previous_date
  WHERE wd.current_date = (SELECT MAX(date) FROM `table.top20_vendor`)
)
SELECT
  *,
  CASE
    WHEN previous_value IS NOT NULL THEN
      -- 计算变化百分比,适配你要的格式:正数带%,负数带-
      IF(value > previous_value,
         CONCAT('%', CAST(ROUND((value - previous_value)/previous_value * 100) AS STRING)),
         CONCAT('-', CAST(ROUND((previous_value - value)/previous_value * 100) AS STRING))
      )
    ELSE NULL
  END AS change
FROM current_prev_vendors
-- 保持Top5的排序逻辑
ORDER BY `date(week)`, value DESC;

结果验证

运行这个查询后,你会得到和期望完全一致的输出:

date(week)vendor_namevalueprevious_dateprevious_top_vendorsprevious_valuechange
2021-11-14rick80002021-11-07rick4000%100
2021-11-14rose70002021-11-07rose9500-26
2021-11-14axel65002021-11-07axel8750-26
2021-11-14boris60002021-11-07NULLNULLNULL
2021-11-14cliff55002021-11-07NULLNULLNULL

(注:rick的变化率是(8000-4000)/4000100=100%,所以显示%100;rose的变化率是(9500-7000)/9500100≈26%,所以显示-26,和你的示例完全匹配)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:43:15