BigQuery空值填充:基于前序非空值逐行生成连续递增整数
解决方案
该需求可直接在BigQuery中实现。
你原有写法失效的原因很简单:窗口里last_value(activity ignore nulls)对所有NULL行返回的都是全局最后一个非空activity值508,加1后所有NULL行的计算结果都是509,没有计入NULL行之间的位置差,自然没法逐行递增。
核心逻辑
不需要复杂的递归,按3步处理即可:
- 提取全表已有的最大非空activity值,作为自动编号的基数
- 按你需要的排序规则给所有行打全局顺序标记,保证行序稳定
- 非空行直接保留原activity值,NULL行按自身排序位置,在基数上逐行+1生成连续编号
可直接运行的SQL代码
WITH base AS ( SELECT *, -- 全局排序规则:非空activity按值升序在前,NULL行在后,和你原有排序逻辑一致 ROW_NUMBER() OVER (ORDER BY activity IS NULL, activity) AS global_sort_id, -- 取历史最大已存在的activity编号 MAX(activity) OVER () AS last_manual_id FROM `rax-datamart-dev.marketing.auto_budget_framework` ), null_with_seq AS ( SELECT *, -- 给所有NULL行单独生成从1开始的连续序号 IF( activity IS NULL, ROW_NUMBER() OVER (PARTITION BY activity IS NULL ORDER BY global_sort_id), 0 ) AS null_auto_seq FROM base ) SELECT budget_id, activity, region, execution_window, -- 非空行保留原值,NULL行=历史最大编号+自身在NULL组的序号 IF(activity IS NULL, last_manual_id + null_auto_seq, activity) AS new_activity FROM null_with_seq ORDER BY global_sort_id
运行效果
针对你给出的样例数据,返回结果完全符合预期:
| budget_id | activity | region | execution_window | new_activity |
|---|---|---|---|---|
| 000507_Corporate | 507 | Corporate | 2022 | 507 |
| 000508_AMERICAS | 508 | AMERICAS | 2022Q2 | 508 |
| NULL | NULL | c | b | 509 |
| NULL | NULL | c | b | 510 |
如果需要调整NULL行的生成顺序(比如按execution window、region字段排序后再生成编号),只需要修改窗口函数中
ORDER BY后的字段即可,不需要改动核心计算逻辑。
内容的提问来源于stack exchange,提问作者runner16
相关产品推荐
相关产品推荐

