0

我有一个看起来像这样的查询,它得到一个百分比:

SELECT SUM(convert(decimal(3,2),
          CASE WHEN Status_ID = 1 AND State_ID = 14 THEN 1 ELSE 0 END))/
          SUM(convert(decimal(3,2),CASE WHEN State_ID = 14 THEN 1 ELSE 0 END)) * 100
FROM SomeTable

在正常情况下,这可能会返回类似 59.77803 的内容。但事实证明,当第二个 SUM(分母)可能为 0 时,存在(正确的)情况。有谁知道一种方法来解释这种情况并避免除以 0 异常?

我正在使用 SQL Server 2005。谢谢。

4

6 回答 6

2

我可能会使用 NULL 来表示无法计算,但这取决于您在问题域中的意图(代码扩展以显示正在发生的事情):

SELECT SUM(convert(decimal(3,2),
                   CASE WHEN Status_ID = 1 AND State_ID = 14 THEN 1 ELSE 0 END)
          )
       /
       NULLIF(
           SUM(convert(decimal(3,2),
                       CASE WHEN State_ID = 14 THEN 1 ELSE 0 END)
           )
           , 0
       )
       * 100
FROM SomeTable

当表中没有行,因此分母为零时的结果 - 被转换为 NULL,因此整个表达式最终为 NULL。

该代码也可以简化一点(可能是因为它已经是一个简化的玩具问题):

SELECT SUM( convert(decimal(3,2), CASE WHEN Status_ID = 1 THEN 1 ELSE 0 END) )
       /
       NULLIF( convert(decimal(3,2), COUNT(*)), 0 )
       * 100
FROM SomeTable
WHERE State_ID = 14

作为将许多不同的事物组合到一个查询中的示例:

SELECT CASE WHEN State_ID = 14 THEN 'State_ID = 14'
            WHEN State_ID IN (1, 2, 3) THEN 'State_ID IN (1, 2, 3)'
            ELSE 'DEFAULT'
       END AS Category
       ,SUM(convert(decimal(3,2),
                   CASE WHEN Status_ID = 1 THEN 1 ELSE 0 END)
          )
       /
       convert(decimal(3,2), COUNT(*))
       * 100
FROM SomeTable
GROUP BY CASE WHEN State_ID = 14 THEN 'State_ID = 14'
            WHEN State_ID IN (1, 2, 3) THEN 'State_ID IN (1, 2, 3)'
            ELSE 'DEFAULT'
       END
于 2010-08-18T20:36:41.503 回答
1

问问自己,当分母为 0 时,你想返回什么结果?
然后基于该修复相应的查询。

没有好的内置方法可以做到这一点。这是一个业务逻辑的事情。

于 2010-08-18T19:58:01.940 回答
1

如果我没看错,这应该有效:

SELECT SUM(convert(decimal(3,2), 
          CASE WHEN Status_ID = 1 THEN 1 ELSE 0 END))/ 
          SUM(convert(decimal(3,2),1)) * 100 
FROM SomeTable 
WHERE State_ID = 14 
于 2010-08-18T20:00:37.520 回答
0
SELECT SUM(convert(decimal(3,2),
          CASE WHEN Status_ID = 1 AND State_ID = 14 THEN 1 ELSE 0 END))/
          SUM(convert(decimal(3,2),CASE WHEN State_ID = 14 THEN 1 ELSE 0 END)) + 0.00000000001 * 100
FROM SomeTable
于 2010-08-18T19:56:21.973 回答
0

为避免除以 0 异常,您可以使用接受分子、分母和默认值的函数在分母为 0 时传递。并调用该函数进行除法。

CREATE FUNCTION [dbo].[fn_divide] 
(
    @numerator DECIMAL(3,2),@denominator DECIMAL(3,2),@default DECIMAL(3,2)
)  
RETURNS DECIMAL(3,2) 

AS  BEGIN

 DECLARE @result DECIMAL(3,2)

 IF @denominator = 0
 BEGIN
    set @result=@default
 END
ELSE
 BEGIN
    set @result=@numerator/@denominator
 END 

  return @result
END
于 2010-08-18T20:11:56.347 回答
0

真正的问题是,当您尝试除以零时,“答案”应该是什么?我会成功NULL的,所以尝试这样的事情:

DECLARE @x int

set @x=5
select 1.0/NULLIF(@x,0)

set @x=0
select 1.0/NULLIF(@x,0)

输出:

---------------------------------------
0.200000000000

(1 row(s) affected)


---------------------------------------
NULL

(1 row(s) affected)

你的代码是:

SELECT SUM(convert(decimal(3,2), CASE
                                     WHEN Status_ID = 1 AND State_ID = 14 THEN 1 
                                     ELSE 0 
                                 END
                  )
          ) 
        /
        SUM(convert(decimal(3,2),CASE
                                     WHEN State_ID = 14 THEN 1 
                                     ELSE NULL   --<<<<<<<<<<<<force null if div by zero
                                 END
                   )
           )
        * 100
FROM SomeTable

我不太了解WHEN Status_ID = 1 AND State_ID = 14 THEN 1,但那是 OPs 代码。

于 2010-08-18T20:25:27.463 回答