在SQL中的WHERE子句中使用IF / THEN或CASE

时间:2011-07-25 13:47:51

标签: sql sql-server

我被分配了更新中型公司的EEO调查和报告的任务。我正在处理一个存储过程来填充报告。一切都很好,但语法问题。其中一个要求是动态允许用户按EEO作业组编号过滤结果。加载报表页面时,它会填充所有作业组合并的表格。我在页面上放置了一个DropDownList,允许用户选择10个EEO作业组中的一个,或者默认情况下,选择所有作业组(无过滤)。 DDL执行回发并填充参数; @intEeoJobGroupID。表中实际上没有0 ID值,仅在DDL中。如果传递的参数@intEeoJobGroupID = 0,我希望(usp)查询使用一组WHERE语句,如果@intEeoJobGroupID<> 0.(如果参数<> 0,则有效地添加另一个AND语句)

我想返回多少EEO记录满足查询要求的计数。我尝试了许多不同格式的IF / THEN和CASE,似乎无法正确使用语法。在下面的示例中,我收到消息“THEN语句中第一个=附近的语法错误,以及关键字ELSE。

任何提示?

DECLARE @intEeoJobGroupID INT

SELECT
     COUNT (E.intEeoID)

FROM
     dbo.NewEEO AS E 
WHERE 
    CASE WHEN @intEeoJobGroupID = 0

    THEN
             E.intGenderID = 1
         AND E.intRaceID = 2

    ELSE
             E.intGenderID = 1
         AND E.intRaceID = 2
         AND E.intEeoJobGroupID = @intEeoJobGroupID

4 个答案:

答案 0 :(得分:5)

你做得太复杂了:

WHERE E.intGenderID = 1 
    AND E.intRaceID = 2 
    AND (E.intEeoJobGroupID = @intEeoJobGroupID OR @intEeoJobGroupID = 0)

正如其他人已经提到的那样,您现有的语法错过了“END”,但它仍然不适用于添加的语法。为了在将来做到这一点,您可以尝试做的一件事是记住SQL中的CASE表达式只是:表达式。它们不是语句,因为您可能习惯使用c#代码中的if语句。您不使用CASE进行流控制,以便按照您的尝试来定义块。

答案 1 :(得分:3)

不要尝试从CASE语句返回boolean。而是返回一些值,然后在CASE语句之外检查(然后产生一个布尔值)。

CASE WHEN @mode = 1 THEN CASE WHEN <Condition1> THEN 1 ELSE 0 END
     WHEN @mode = 2 THEN CASE WHEN <Condition2> THEN 1 ELSE 0 END
END
=
1

注意:这将创建可怕的执行/解释计划和完全的nerf性能。您最好使用真正的 IF块和真正的查询,或者可能使用工会......

IF @mode = 1
  SELECT foo FROM bar WHERE <Condition1>
ELSE IF @mode = 2
  SELECT foo FROM bar WHERE <Condition2>

或者...

SELECT foo FROM bar WHERE <condition1> AND @mode = 1
UNION ALL
SELECT foo FROM bar WHERE <condition2> AND @mode = 2

为了防止大量重复代码,您可能会发现将大量查询封装在VIEW中会很有帮助。

答案 2 :(得分:2)

您无法比较案例条件的结果。如果您在case子句中使用where,则需要位于运算符的一侧:

CASE @case_value
WHEN 0 THEN
     some_column
ELSE
     some_other_column
END = @some_value

但是,如果您尝试使您的实际条件符合此规则,那么您最终将完全不使用case语句,正如@Joel指出的那样。

答案 3 :(得分:0)

你必须添加

  

在案件的最后。