求和转换列时出错

时间:2012-09-29 17:12:38

标签: sql sql-server view

我在SQL Server中有一个包含2列的表:Question_askedResponse

Response列的数据类型为varchar(500),并保留用户对Question_asked列中所持问题的回复

我使用以下SQL语句创建了一个视图V_age_attr

select 
    question_asked, cast(Response as integer) 
from 
    main_table 
where 
    question_asked = 'What is your age'

如果我运行一个简单的SQL查询,结果将按预期返回。但在某些情况下,例如通过查询使用sum / group时。我收到一个错误消息(我得到的实际消息):

  将varchar值'2011-08-13 00:00:00'转换为数据类型int

时,

转换失败

在表main_table中,其中一个问题是start_date,因此列Response确实在表中保存了日期值,但在我创建的视图中没有。

同样,我可以运行一个select查询并检查cast(Response as integer)的所有值,它们都是整数值。

我的主要问题是:任何人都可以告诉我这是否是SQL Server 2008 R2中已知/预期的行为,和/或是否有其他人有另一种方法从这种类型的表中获取值的子集而不是创建视图?

谢谢

3 个答案:

答案 0 :(得分:3)

唉,按isnumeric过滤并不一定有效。 SQL是一种描述性语言,而不是一种过程语言。因此,操作不必按指定的顺序工作。

在这种情况下,SQL Server将在读取数据时尝试进行转换,然后应用过滤器。太晚了。你有一个错误。

case语句是保证评估顺序的唯一语句,至少在不涉及聚合函数时。以下内容应解决转换问题:

select question_asked,
       (case when isnumeric(Response) = 1 and
                  Response not like '%.%'
             then cast(Response as int)
        end) as Response
from main_table
where question_asked = 'What is your age' 

此版本还会在Response中检查小数点。当有小数点时,ISNUMERIC将返回1,但这也将导致转换失败。

答案 1 :(得分:1)

鉴于Martin has highlighted的错误,我实际上会在CASE语句中使用原始条件,该条件将适用于任何数字类型,不限于Gordon的int解释。比ISNUMERIC更好,但从SQL Server 2012起,TRY_CONVERT会更好。您希望SQL Server可以在WHERE子句中重用条件解析来协助SELECT,反之亦然。

select 
    question_asked, case when question_asked = 'What is your age'
                         then cast(Response as integer)
                         end
from 
    main_table 
where 
    question_asked = 'What is your age'

答案 2 :(得分:0)

使用ISNUMERIC进行过滤 - 可能存在非整数数据作为响应,这些数据会破坏聚合函数。

SELECT
 question_asked,
 CASE(response AS INT)
FROM
 main_table
WHERE
 question_asked = 'What is your age'
 AND ISNUMERIC(response) = 1

编辑:如果仍然无效,您可能需要在response列上进行更积极的类型检查。看看这里的回复:

How to get if a string is a number in T-SQL