将varchar转换为十进制算术溢出错误将varchar转换为数据类型numeric

时间:2014-09-15 21:11:42

标签: sql sql-server casting average

请一些人帮我解决这个简单的SQL查询

SELECT avg(CAST(NULLIF(Sim1SS,0.0) as DECIMAL)) as MTN ,
avg(CAST(NULLIF(Sim2SS,0.0) as DECIMAL)) as Vodacom

FROM [Networks].[dbo].[Device] 

我收到以下错误:

  

将varchar转换为数据类型numeric的算术溢出错误。

以下是SS列的示例:

28,99
10,99
11,99
NULL
NULL
31,99
31,99
NULL

1 个答案:

答案 0 :(得分:2)

你有两个问题。首先,当您在字符串数据类型上使用NULLIF时,您将隐式地将其转换为数字数据类型。您已将0.0指定为第二个参数。 SQL Server不知道要选择什么,它可能会选择float或其他内容。将字符串转换为数字

后,应调用NULLIF

其次,您尚未指定DECIMAL数据类型的精度和比例。根据{{​​3}},DECIMAL数据类型的默认精度和比例是18,0。如果您未指定比例,则数字将被截断。

所以,正确的语法应该是:

SELECT avg(NULLIF(CAST(Sim1SS as DECIMAL(18,2)), 0.00)) as MTN,
       avg(NULLIF(CAST(Sim2SS as DECIMAL(18,2)), 0.00)) as Vodacom
FROM [Networks].[dbo].[Device] 

顺便说一句,如果小数点符号的区域设置不是句点(.),那么您需要进行替换:

SELECT avg(NULLIF(CAST(REPLACE(Sim1SS, ',', '.') as DECIMAL(18,2)), 0.00)) as MTN,
       avg(NULLIF(CAST(REPLACE(Sim2SS, ',', '.') as DECIMAL(18,2)), 0.00)) as Vodacom
FROM [Networks].[dbo].[Device] 

如果您的数据未经过清理,则需要使用ISNUMERIC函数,如下所示:

SELECT avg(NULLIF(case when isnumeric(Sim1SS)=1 then CAST(REPLACE(Sim1SS, ',', '.') as DECIMAL(18,2)) end, 0.00)) as MTN,
       avg(NULLIF(case when isnumeric(Sim2SS)=1 then CAST(REPLACE(Sim2SS, ',', '.') as DECIMAL(18,2)) end, 0.00)) as Vodacom
FROM [Networks].[dbo].[Device]