You need to enable JavaScript to run this app. GoogleSQL中按收入分位数分组企业 如何仅返回公司与分位段
优惠活动
大模型
产品
解决方案
定价
更多

GoogleSQL中按收入分位数分组企业 如何仅返回公司与分位段

报错原因及无额外子查询修复方案

你修改代码后报错的核心原因是:CASE判断逻辑中引用了Percentile50_Max、Percentile90_Max两个字段,这两个字段既不是聚合函数结果,也不在GROUP BY的分组字段列表中,不符合SQL的分组聚合语法规则。
不需要新增额外子查询,因为这两个分位值是CROSS JOIN得到的全局唯一固定值,只要用聚合函数(比如MAX/MIN,不影响计算结果)包裹即可,修改后的可运行代码如下:

SELECT 
  company,
  CASE
    WHEN SUM(revenue) > MAX(Percentile90_Max) THEN "Top"
    WHEN SUM(revenue) >= MAX(Percentile50_Max) THEN "Middle"
    ELSE "Bottom"
  END as percentile_section
FROM revenue_table
CROSS JOIN  
  (SELECT 
     APPROX_QUANTILES(revenue,100)[offset(50)] As Percentile50_Max,
     APPROX_QUANTILES(revenue,100)[offset(90)] As Percentile90_Max
   FROM 
     (SELECT 
        company,
        SUM(revenue) as revenue
      FROM revenue_table
      GROUP BY 1
     )
  )
GROUP BY 1
ORDER BY SUM(revenue) DESC

效率相关说明

你当前使用的子查询+CROSS JOIN的方案已经属于最优方案之一,计算全局分位的核心开销(先聚合所有公司的总营收、再扫描计算分位数)是不可避免的。
子查询并不是唯一的最优方案,你也可以用窗口函数的写法实现,逻辑更简洁,GoogleSQL优化器会生成和原方案几乎一致的执行计划,效率没有本质差异:

WITH company_total_revenue AS (
  -- 先聚合每个公司的总营收
  SELECT company, SUM(revenue) AS total_revenue
  FROM revenue_table
  GROUP BY 1
)
SELECT
  company,
  CASE
    WHEN total_revenue > APPROX_QUANTILES(total_revenue,100) OVER()[offset(90)] THEN "Top"
    WHEN total_revenue >= APPROX_QUANTILES(total_revenue,100) OVER()[offset(50)] THEN "Middle"
    ELSE "Bottom"
  END AS percentile_section
FROM company_total_revenue
ORDER BY total_revenue DESC

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 16:27:04