我有一个看起来像这样的查询,并且获得了一个百分比:
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.谢谢。
答案 0 :(得分: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
答案 1 :(得分:1)
问问自己,当分母为0时,你想要返回的结果是什么? 然后根据它相应地修复查询。
没有好的内置方式来做到这一点。这是一个商业逻辑。
答案 2 :(得分: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
答案 3 :(得分: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
答案 4 :(得分: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
答案 5 :(得分: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
,但那是OP代码。