即使我排除零案例,在SQL中除以零错误?

时间:2015-07-02 20:14:00

标签: sql sql-server

以下是我一直试图运行的代码:

SELECT C.* FROM
(SELECT 
B.[OUTSIDE_ROW],
B.[INSIDE_ROW],
B.[r_HU_vac_ns],
B.[r_HU_vac_ns_MOE],
CASE WHEN B.[r_HU_vac_ns] = 0 THEN 999 ELSE B.[r_HU_vac_ns_MOE]/B.[r_HU_vac_ns] END AS [PCT]
FROM
(SELECT 
A.[OUTSIDE_ROW], 
A.[INSIDE_ROW], 
(A.[HU_VACANT] - A.[HU_VACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT] AS [r_HU_vac_ns], 
(1/A.[HU_VACANT]) * POWER( 
CASE WHEN ((A.[HU_VACANT] - A.[HU_VACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT]) * POWER(A.[HU_VACANT_MOE], 2) < POWER(A.[HU_VACANT_MOE], 2) +     POWER(A.[HU_VACANT_SEASONAL_RECREATIONAL_MOE], 2) THEN POWER(A.[HU_VACANT_MOE],     2) + POWER(A.[HU_VACANT_SEASONAL_RECREATIONAL_MOE], 2) - (((A.[HU_VACANT] - A.    [HU_vACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT]) * POWER(A.[HU_VACANT_MOE], 2))
ELSE POWER(A.[HU_VACANT_MOE], 2) + POWER(A.    [HU_VACANT_SEASONAL_RECREATIONAL_MOE], 2) + (((A.[HU_VACANT] - A.    [HU_vACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT]) * POWER(A.[HU_VACANT_MOE], 2)) END, 0.5) AS [r_HU_vac_ns_MOE]
FROM
(SELECT 
[OUTSIDE_ROW], 
[INSIDE_ROW], 
SUM([ESTIMATE_1]) AS [HU_VACANT], 
POWER(SUM(POWER([MOE_1], 2)), 0.5) AS [HU_VACANT_MOE],
SUM([ESTIMATE_2]) AS [HU_VACANT_SEASONAL_RECREATIONAL],
POWER(SUM(POWER([MOE_2], 2)), 0.5) AS [HU_VACANT_SEASONAL_RECREATIONAL_MOE]
FROM #TEST_TABLE
GROUP BY [OUTSIDE_ROW], [INSIDE_ROW]) A
WHERE A.[HU_VACANT] > 0) B ) C 
WHERE C.[PCT] < 0.2

每次运行时,都会出现以下错误:

Msg 8134, Level 16, State 1, Line 533
Divide by zero error encountered.

但是,如果我取消最后一行代码(以下WHERE子句),代码运行正常:

WHERE C.[PCT] < 0.2

仅仅从查看我的查询,谁能告诉我我做错了什么?我以为我使用下面的CASE WHEN语句删除了所有零PCT值,所以这个错误令我困惑:

 CASE WHEN B.[r_HU_vac_ns] = 0 THEN 999 ELSE B.[r_HU_vac_ns_MOE]/B.[r_HU_vac_ns] END AS [PCT]

如果有帮助,PCT将被转换为浮点数。

感谢。

2 个答案:

答案 0 :(得分:5)

SQL Server保留重新排列计算的权利。这意味着SELECT中的计算可能会在过滤发生之前发生。即使过滤器位于子查询和CTE中也是如此。

保证计算顺序的唯一方法是CASE。但是,我认为使用ANSI标准函数NULLIF()更容易。而不是像这样的逻辑:

(A.[HU_VACANT] - A.[HU_VACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT] AS [r_HU_vac_ns],

做的:

(A.[HU_VACANT] - A.[HU_VACANT_SEASONAL_RECREATIONAL])/NULLIF(A.[HU_VACANT], 0) AS [r_HU_vac_ns],

答案 1 :(得分:0)

而不是使用

过滤掉记录
WHERE A.[HU_VACANT] > 0

您应该过滤掉根级别的记录

having SUM([ESTIMATE_1]) > 0

您也可以使用nullif函数,但这会导致在零

时产生NULL