红移数据库的零除谜题

10

我在这段代码中遇到了除以0的错误:

CASE
WHEN DENOMINATOR >= 0
THEN SUM(INT1 * INT2 / DENOMINATOR)
ELSE 0
END AS RATIO
然而,当我改用以下代码时,它起作用了。
CASE
WHEN DENOMINATOR >= 0
THEN SUM(INT1) * INT2 / DENOMINATOR
ELSE 0
END AS RATIO

能否有人帮我理解原因,以便我将来可以避免这种情况?顺便说一句,第一个示例在Vertica中有效。我意识到只对需要求和的部分进行求和而不是在求和之前进行计算是更好的编程实践。 但是,我仍然很好奇。


2
CASE WHEN DENOMINATOR >= 0 似乎不对,如果你想避免除以0的错误,你是不是应该使用 > 0 而不是 >= 0 或者如果你想允许负数,就使用 <> 0。 - xQbert
我猜测负数分母应该为0。因此else语句中只需使用>而不是>=。 - xQbert
负数问题与问题无关。关键是分母不能为零。我试图理解为什么一个可以工作而另一个会给我一个错误。 - cjremley
我想我不明白为什么一个有效而另一个无效的,如果问题本身的前提是错误的话,那么它是否重要。在任何时候,都不应该允许分母为0。因此,为什么你的情况大于或等于0。连“等于”也似乎是错的。至于为什么一个有效而另一个无效...我需要看到更多的SQL代码,除非你按int/denominator分组;并在某种情况下消除了零。我需要一个小的测试案例来更好地理解。 - xQbert
1个回答

35

我认为避免除以零的最好方法是使用 nullif() 函数:

SUM(INT1 * INT2 / NULLIF(DENOMINATOR, 0))

或者:
SUM(INT1) * INT2 / NULLIF(DENOMINATOR, 0)

这将返回NULL,我认为在除以零的情况下更合理。如果您喜欢,可以添加COALESCE()来获取0


如何处理DENOMINATOR的负值? - Jon Scott
@JonScott...你需要一个CASE来处理它们。 - Gordon Linoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接