如何在BigQuery中计算累计乘积的累计和
解决方案
这个需求属于反向累积乘积的滚动求和场景,无需使用PIVOT,直接用窗口函数即可实现,支持任意行数的计算,性能稳定。
核心实现逻辑
你需要的计算可以拆解为两步窗口运算:
- 按
x降序排序,计算从当前行到最后一行的反向累计乘积 - 对第一步得到的反向累计乘积,再按
x降序做累计求和,得到最终目标值
基础实现(y均为正数场景)
如果你表中y列所有值都为正数,可以直接沿用你已知的对数累积乘积方案,仅调整排序规则即可:
WITH reverse_cum_prod AS ( SELECT x, y, EXP(SUM(LN(y)) OVER (ORDER BY x DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) AS rev_prod FROM 你的表名 ) SELECT x, y, SUM(rev_prod) OVER (ORDER BY x DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS target_result FROM reverse_cum_prod ORDER BY x;
兼容全场景实现(y可正可负可零)
如果y存在负数、零的情况,对数计算会报错,可以改用递归CTE实现反向累计乘积,兼容所有合法数值场景:
WITH sorted_data AS ( SELECT x, y, ROW_NUMBER() OVER (ORDER BY x DESC) AS rn FROM 你的表名 ), recursive_prod (rn, x, y, rev_prod) AS ( SELECT rn, x, y, y FROM sorted_data WHERE rn = 1 UNION ALL SELECT s.rn, s.x, s.y, s.y * r.rev_prod FROM sorted_data s INNER JOIN recursive_prod r ON s.rn = r.rn + 1 ) SELECT x, y, SUM(rev_prod) OVER (ORDER BY rn ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS target_result FROM recursive_prod ORDER BY x;
方案优势
- 没有行数限制,支持超过100行甚至上万行的计算
- 时间复杂度为O(n),性能远高于PIVOT方案
- 所有主流支持窗口函数的数据库(MySQL 8.0+、PostgreSQL、SQL Server、Oracle等)都可以直接运行
内容的提问来源于stack exchange,提问作者Timogavk
相关产品推荐
相关产品推荐

