Redshift中CASE筛选针对整数值出现异常行为的技术咨询
Redshift中CASE计算列与WHERE过滤逻辑不一致的原因
这是Redshift的预期行为,根源在于它对整数除法的处理规则和SQL Server存在差异,并非Bug。
问题本质
你的测试代码中,num和next_num默认是整数类型(INT),Redshift遵循PostgreSQL的整数除法逻辑:两个整数相除时,会直接截断小数部分,仅返回整数结果。而SQL Server的整数除法规则不同,会在部分场景下隐式转换为浮点运算保留小数。
以你提供的代码为例:
with tt as ( select 90 AS num, 91 AS next_num ) select num, next_num, (num-next_num) / num AS result, -- 整数除法:(-1)/90 = 0(截断小数) case when (num-next_num) / num between -0.2 and 0.2 then 'yes' else 'no' end calculation -- 0在范围内,返回'yes' from tt where calculation = 'no'
此时calculation结果为'yes',WHERE子句calculation='no'自然不会返回数据。而当你把CASE条件直接写入WHERE时,比如:
where (num-next_num)/num between -0.2 and 0.2
这里的计算依然是整数除法,结果为0,条件成立,同样不会返回calculation='no'的行,这就是你所说的“无效果”。
若你的实际测试场景是差值超出±0.2的情况(比如num=100、next_num=121),整数除法下(100-121)/100会被截断为0,CASE返回'yes',WHERE无法过滤出预期的'no'行;但将num和next_num声明为NUMERIC类型后,除法会保留小数部分得到-0.21,CASE返回'no',WHERE子句就能正确过滤到该行,这就是你所说的“恢复正常”。
解决方案
要避免这种逻辑不一致的问题,你可以:
- 显式将整数转换为NUMERIC/浮点类型后再执行除法,比如:
(num::NUMERIC - next_num::NUMERIC) / num::NUMERIC - 在定义表结构或CTE时,直接使用NUMERIC/DECIMAL类型存储数值,从根源上避免整数除法的隐式截断
内容的提问来源于stack exchange,提问作者omer9742
相关产品推荐
相关产品推荐

