操作顺序在哪里

时间:2012-05-14 13:47:04

标签: sql tsql sql-order-by

这是我的sql

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

问题是遗留数据是OptionID = 6中的字符串。当我运行上面的查询时,它给了我

  

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

我确认了QuesID = 1中的所有数据,而OptionId IN(2,5)中的所有数据都是浮点数据。看起来SQL首先在做这个sql的数学部分,无论如何要在运行AnswerValue比较之前检查OptionID吗?还是我完全偏离基地?

5 个答案:

答案 0 :(得分:3)

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

所以,是的,正如你在我写这篇文章时发布的那样,扔进去了

AND isnumeric(AnswerValue) = 1

将处理此问题,因为SQL似乎在其过程的早期对其进行了评估。

答案 1 :(得分:1)

想出来,我刚刚将SQLNUMERIC添加到SQL中并对其进行了排序。

答案 2 :(得分: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表达式来执行更多逻辑 - 通常,这将导致您表达所有条件并使结果等于0或{ {1}},然后执行与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 1

答案 3 :(得分: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

答案 4 :(得分: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