BigQuery窗口函数的PARTITION子句可以使用列别名吗?
问题原因说明
这个报错不是语法编写错误,是BigQuery遵循标准SQL的执行逻辑导致的:同层级SELECT子句中定义的列别名,不支持直接在同层级的窗口函数PARTITION BY子句中引用。
底层逻辑
SQL的标准执行顺序如下,别名是在SELECT子句的最终投影阶段才会被绑定生效,而同层级的窗口函数运算在别名绑定前就会执行,因此无法识别提前引用的别名:
- 第一步:执行FROM/JOIN加载表数据
- 第二步:执行WHERE过滤数据
- 第三步:执行GROUP BY分组
- 第四步:执行聚合函数计算
- 第五步:执行HAVING过滤分组结果
- 第六步:执行窗口函数运算
- 第七步:执行SELECT子句的字段投影、绑定别名
- 第八步:执行DISTINCT去重
- 第九步:执行ORDER BY排序
- 第十步:执行LIMIT截取结果
不止BigQuery,PostgreSQL、MySQL 8.0+等绝大多数主流关系型数据库都遵循该执行逻辑。
可行的修复方案
方案1:直接复用逻辑到PARTITION BY子句(简单快速)
把定义country_alias的CASE语句直接复制到PARTITION BY中即可,不需要调整整体结构:
select year , case when g.country = 'Australia' then 'Australia' else 'Other' end as country_alias , count(distinct g.user_id) OVER (PARTITION BY case when g.country = 'Australia' then 'Australia' else 'Other' end) as user_count_country from people as g where year = 2021 order by 1,2
方案2:用CTE提前定义别名(可读性高、易维护)
先通过CTE计算好别名字段,外层查询再调用窗口函数引用别名,避免重复写相同逻辑:
with base_data as ( select year, user_id, case when country = 'Australia' then 'Australia' else 'Other' end as country_alias from people where year = 2021 ) select year, country_alias, count(distinct user_id) over (partition by country_alias) as user_count_country from base_data order by 1,2
内容的提问来源于stack exchange,提问作者crazy8
相关产品推荐
相关产品推荐

