Sql 为什么红移会给我一个除以零的错误?

Sql 为什么红移会给我一个除以零的错误?,sql,subquery,amazon-redshift,division,divide-by-zero,Sql,Subquery,Amazon Redshift,Division,Divide By Zero,我知道红移中的浮点存在一些陷阱,但我无法克服 我有col1和col2列,希望创建一个简单的除法作为calc。col1和col2有时为零,所以我使用col2>0的地方。col1和col2没有空值。这很好: select col1*1.0/col2 as calc from t1 where col1 > 0 and col2 > 0 但如果我在where子句中为calc使用任何值,我会得到错误: select calc from (select col1*1.0/col2 as c

我知道红移中的浮点存在一些陷阱,但我无法克服

我有col1和col2列,希望创建一个简单的除法作为calc。col1和col2有时为零,所以我使用col2>0的地方。col1和col2没有空值。这很好:

select col1*1.0/col2 as calc
from t1
where col1 > 0 and col2 > 0
但如果我在where子句中为calc使用任何值,我会得到错误:

select calc from 
(select col1*1.0/col2 as calc
from t1
where col1 > 0 and col2 > 0) 
where calc < 1 -- error here for any value, gt or lt

SQL Error [500310] [57014]: [Amazon](500310) Invalid operation: Divide by zero;

我尝试了很多方法,包括计算不同的值,转换为十进制或浮点,但我得到了相同的错误。为什么?

红移可能会优化查询的操作树,使select子句中的除法在where子句中的条件之前进行计算

如果满足以下条件,则可以使用null解决此问题:


使用*1.0让我想知道col1和col2的数据类型是int还是numeric。它们是浮点数吗?是的,它们被视为整数,因此选择1/2返回0。select 1.0/2返回0.5。确切地说,这是一个隐式转换,正如GMB所说,Redshift正在以它所看到的优化执行的最佳方式编译您的查询。这样做并不尊重隐式铸造。您可以尝试显式强制转换来强制执行-col1::float/col2::float。
select calc 
from (
    select col1 * 1.0 / nullif(col2, 0) as calc
    from t1
    where col1 > 0 and col2 > 0
) 
where calc < 1