0

这是我的sql

SELECT * FROM Answers
WHERE QuesID = 1 AND OptionID IN (2,5) AND CONVERT(float, ISNULL(AnswerValue, 0)) < 300

问题是 OptionID = 6 中有旧数据是字符串。当我运行上述查询时,它给了我

将数据类型 varchar 转换为浮点数时出错。

我确认 QuesID=1 和 OptionId IN (2,5) 中的所有数据都是浮点数据。似乎 SQL 是先做这个 sql 的数学部分,有没有让它在运行 AnswerValue 比较之前检查 OptionID?还是我完全不在基地?

4

5 回答 5

3

您无法真正控制 SQL 将“解析”子句中的WHERE子句的顺序。我做了一些快速测试,如果只为 QuesId=3 输入了一个字符串值,它就起作用了。

所以,是的,正如你在我写这篇文章时发布的那样,折腾

AND isnumeric(AnswerValue) = 1

将处理此问题,因为 SQL 似乎在其过程中较早地对其进行评估。

于 2012-05-14T13:58:08.663 回答
1

想通了,我只是将 ISNUMERIC 添加到 SQL 中,然后就解决了。

于 2012-05-14T13:56:30.397 回答
1

如果CASE搜索条件匹配,表达式只会评估其结果表达式,因此您可以尝试:

SELECT * FROM Answers
WHERE
    CASE WHEN QuesID = 1 AND OptionID IN (2,5) THEN
        CONVERT(float, ISNULL(AnswerValue, 0))
    ELSE
        500
    END < 300

对于更复杂的表达式,您可以选择使用嵌套CASE表达式来执行更多逻辑 - 通常,这将导致您表达所有条件并使结果等于0or 1,然后执行最终的外部比较1

WHERE
1 = CASE WHEN <Condition 1> THEN
        CASE WHEN <Condition 1, Subcondition 1> THEN 0
             WHEN <Condition 1, Subcondition 2> THEN 1
        END
         WHEN <Condition 2> THEN
        CASE WHEN <Condition 2, Subcondition 1> THEN 1
             WHEN <Condition 2, Subcondition 2> THEN 0
        END
    END

仅当为真Condition 1时才会评估两个子条件(对于也是如此)Condition 1Condition 2

于 2012-05-14T14:14:23.793 回答
0

如果升级到 SQL Server 2012,则可以使用 TRY_CONVERT。它是专有的,但它确实解决了问题。

SELECT * FROM Answers
WHERE QuesID = 1
AND TRY_CONVERT(int,OptionID) IN (2,5)
AND CONVERT(float, ISNULL(AnswerValue, 0)) < 300
于 2012-05-14T14:55:49.527 回答
0

如果您想保证操作的顺序,并且性能不是那么重要,您可以声明一个表变量来存储前两个条件的结果,然后根据最终条件过滤临时表。例如

declare @tempAnswers table (quesID int, optionid int, answervalue varchar(50))

insert into @tempAnswers
select * 
from Answers
where QuesID = 1 and OptionID in (2,5) 

select * from @tempAnswers
where convert(float, isnull(AnswerValue, 0)) < 300
于 2012-05-14T14:46:16.177 回答