如何解决Athena中的浮点精度问题?分组占比结果多次运行不一致
问题分析
你查询结果不一致的核心原因是:窗口SUM函数中添加了order by子句,导致计算的是累计求和而非分组总求和。
当窗口函数包含order by时,SQL默认会将窗口框架设置为ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,也就是从分组第一行累加到当前行的金额总和,而非整个col1, col2, col3分组的总金额。由于行的返回顺序可能每次查询略有变化(除非有明确的唯一排序键),累计求和的结果会跟着变化,最终导致explode_percent每次结果不同。
另外,explode_amount的partition by包含了col4,如果col4是每行唯一标识,那么这个sum结果其实等于当前行的amount,这可能也不符合你“分组总和”的预期。
修正后的查询
要计算每行amount占col1, col2, col3分组总金额的比例,需要确保窗口SUM计算的是整个分组的总和,去掉窗口函数内的order by即可:
SELECT amount, -- 若explode_amount是col1+col2+col3+col4分组的总和,移除order by sum(amount) over ( partition by col1, col2, col3, col4 ) as explode_amount, COALESCE( amount / NULLIF( -- 计算col1+col2+col3分组的总金额,移除order by SUM(amount) over( partition by col1, col2, col3 ), 0 ), 0 ) as explode_percent FROM my_table
如果你的SQL方言要求显式指定窗口框架(部分数据库在partition by后加order by时需明确框架),也可以写成:
SELECT amount, sum(amount) over ( partition by col1, col2, col3, col4 rows between unbounded preceding and unbounded following ) as explode_amount, COALESCE( amount / NULLIF( SUM(amount) over( partition by col1, col2, col3 rows between unbounded preceding and unbounded following ), 0 ), 0 ) as explode_percent FROM my_table
额外说明
- 移除窗口函数内的
order by后,窗口SUM会计算整个分组的总金额,不受行顺序影响,结果会稳定一致。 - 若你原本的
order by是为了保证行的输出顺序,可以将order by移到整个查询的末尾(FROM my_table ORDER BY col2, col3, col4),而非放在窗口函数内部。
内容的提问来源于stack exchange,提问作者djm
相关产品推荐
相关产品推荐

