我在SQL Server中有一个包含2列的表:Question_asked
,Response
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中已知/预期的行为,和/或是否有其他人有另一种方法从这种类型的表中获取值的子集而不是创建视图?
谢谢
答案 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
列上进行更积极的类型检查。看看这里的回复: