0

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

Response列属于数据类型varchar(500),并保存用户对列中保存的问题的响应Question_asked

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

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

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

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

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

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

我的主要问题是:谁能告诉我这是否是 SQL Server 2008 R2 中已知/预期的行为,和/或除了创建视图之外,还有其他人有其他方法从这种类型的表中获取值的子集吗?

谢谢

4

3 回答 3

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' 

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

于 2012-09-29T17:39:56.907 回答
1

鉴于Martin 强调的错误,我实际上会在 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'
于 2012-09-29T21:22:07.457 回答
0

过滤器使用ISNUMERIC- 可能有非整数数据作为响应,这会弄乱聚合函数。

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

编辑:如果这仍然不起作用,您可能需要对您的response列进行一些更积极的类型检查。在此处查看回复:

如何在 T-SQL 中获取字符串是否为数字

于 2012-09-29T17:16:04.767 回答