【问题标题】:CASE Statement in Where clause using Like Operator使用 Like 运算符的 Where 子句中的 CASE 语句
【发布时间】:2018-07-27 11:07:23
【问题描述】:

我在 where 子句中使用 CASE 表达式时遇到问题,据我所知语法是正确的,但出现错误。以下是我的代码:

Where
CASE 
            WHEN (@ItemFor='' and @ItemTo='')
            THEN id like '%'
            ELSE id between @ItemFor and @ItemTo
        END

上面的代码在我看来是正确的,但我收到语法错误提示

关键字“like”附近的语法不正确。

编辑

我有4组参数,都需要去where子句,都是字符串值:

WHERE

        CASE 
            WHEN (@ItemFor='' and @ItemTo='')
                THEN id like '%'
                ELSE id between @ItemFor and @ItemTo
        END
    AND 
        CASE 
            WHEN (@CodeFrom='' and @CodeTo='')
            THEN Code like '%'
            ELSE code between @CodeFrom and @CodeTo
        END

【问题讨论】:

标签: sql sql-server tsql where-clause


【解决方案1】:

您不需要case 表达式。做吧:

where ((@ItemFor = '' and @ItemTo = '') or
       id between @ItemFor and @ItemTo
      )

您的版本不起作用,因为 SQL Server 没有布尔变量。您的 case 表达式试图返回一个布尔表达式,但这样的表达式不是值。

顺便说一句,你可能打算:

where (id >= @itemfrom or @itemfrom = '') and
      (id <= @itemto or @itemto = '')

这允许您只设置一个限制。

【讨论】:

  • 谢谢先生,但是我在这之后的where子句中有更多条件,需要添加AND...
  • 你能帮我解决一个问题吗?我的要求是如果用户在参数中输入一些值,然后需要过滤那些其他值,从数据库中获取所有值。像这样我有 4 个参数
  • @Siva 。 . .添加更多条件。这只是要检查的另一个条件。
  • @Siva 。 . .在回答完问题后修改问题可能是粗鲁的。您已经有了原始问题的答案。修改往往会使这些答案无效。
  • 不,先生,我在回答之前已经编辑过......之后就被编辑过
【解决方案2】:

你可以简化并使用这个条件:

WHERE ((@ItemFor='' and @ItemTo='' AND id like '%') OR id between @ItemFor and @ItemTo)
  AND ((@CodeFrom='' and @CodeTo='' AND Code like '%') OR code between @CodeFrom and @CodeTo)

现在语法是正确的。

此外,id like '%'Code like '%' 毫无意义,因为它们总是正确的。它们可以读作“检查id(或Code)是否是任何东西”,因此它们可以(应该)被删除。

【讨论】:

  • Turczyn 是的,先生.. 但我有 4 个参数的要求,用户可以为单个参数输入全部或不输入值,或者可以输入 1 个值和 3 个空白.. 所以它是动态的,所以试图从中得到一些解决方案
  • @Siva 所以试试我给出的代码 - 它应该完全按照你想要的方式工作:)
  • @Siva 如果你用我的回答解决了你的问题,你应该接受它:)
  • 当然,先生..一旦结果出来,只要尝试就会接受
【解决方案3】:

这可能会解决您的问题:

WHERE 
((@ItemFor = '' and @ItemTo = '' and id like '%') 
or (@ItemFor <> '' and @ItemTo <> '' and id between @ItemFor and @ItemTo))      
AND 
((@CodeFrom = '' and @CodeTo = '' and Code like '%')
 or (@CodeFrom <> '' and @CodeTo <> '' and code between @CodeFrom and @CodeTo))

【讨论】:

    【解决方案4】:

    由于 CASE 无法返回布尔值,因此您必须返回其他内容并进行比较:

    WHERE
      CASE
        WHEN Condition1 THEN 1
        WHEN Condition2 THEN 0
        WHEN Condition3 THEN 1
        ELSE 0
      END = 1
    

    【讨论】:

    • 感谢您的回答.. 但在我的情况下,我应该如何返回值?
    【解决方案5】:

    试试这个方法。

    where (@itemFor='' and @itemto='') OR (id between @itemFor and @itemto)
    

    执行与您的案例案例陈述相同的操作。如果两个变量都为空,则不要过滤 ID 子句。如果变量已填充,请检查范围内的 ID

    请注意,如果您正在执行多个条件,我建议添加额外的括号,例如

    where ( (@itemFor='' and @itemto='') OR (id between @itemFor and @itemto) )
       and (firstName like '%JOE%')
    

    【讨论】:

    • 感谢先生的解决方案
    【解决方案6】:

    解释 CASE WHEN 有什么问题。

    CASE WHEN 返回一个值,您可以根据不同的条件进行选择。
    它会根据匹配的第一个条件返回一个值。
    因此,它不应该返回一个标准。

    下面的例子利用了它。

    WHERE
       (CASE 
        WHEN @ItemFor='' AND @ItemTo='' AND id IS NOT NULL THEN 1
        WHEN id BETWEEN @ItemFor AND @ItemTo THEN 2
        ELSE 0
        END) > 0
       AND
       (CASE 
        WHEN @CodeFor='' AND @CodeTo='' AND Code IS NOT NULL THEN 1
        WHEN Code BETWEEN @CodeFor AND @CodeTo THEN 2
        ELSE 0
        END) > 0
    

    也就是说,关于这个例子。
    在 WHERE 子句中不使用 CASE WHEN 的解决方案可能是更好的方法。

    例子:

    WHERE id IS NOT NULL
      AND Code IS NOT NULL
      AND ((@ItemFor='' AND @ItemTo='') OR (id BETWEEN @ItemFor AND @ItemTo))
      AND ((@CodeFor='' AND @CodeTo='') OR (Code BETWEEN @CodeFor AND @CodeTo))
    

    因为查询优化器更难根据 CASE WHEN 选择最快的执行计划。

    【讨论】:

    • 感谢您的回答,但是对于 Gordon 解决方案如何添加多个条件?你能帮帮我吗?
    • @Siva 您可以在 CASE 中添加更多 WHEN ... THEN ...。但请记住,它们是按顺序进行评估的。 F.e. case when 2=1 then 1 when 2=2 then 2 when 3=3 then 3 end 返回 2。
    • 感谢先生的解决和解释
    • @Siva Btw,我更新了我的答案。我认为仅检查 Id 和 Code 是否为NOT NULLLIKE '%' 具有相同的效果。因为LIKE '%' 在空字符串col='' 上也是如此。
    【解决方案7】:

    我猜你的错误区域

    WHERE
    
        CASE 
            WHEN (@ItemFor='' and @ItemTo='')
                THEN id like '%'                  -------conditional operator in result
                ELSE id between @ItemFor and @ItemTo ---------- conditional operator
        END
    AND 
        CASE 
            WHEN (@CodeFrom='' and @CodeTo='')
            THEN Code like '%'
            ELSE code between @CodeFrom and @CodeTo  -------------conditional operator
        END
    

    你可以试试下面的方法

    WHERE    
    case when (@ItemFor='' and @ItemTo='') and id like '%' 
    Then (case when id >=@ItemFor and id<=@ItemTo then id else end)
    Else 
    case when (@CodeFrom='' and @CodeTo='') and Code like '%' 
    Then (case when code >=@ItemFor and code<=@ItemTo then code else end)
    end
    

    【讨论】:

    • 感谢先生的解决方案和解释
    【解决方案8】:

    试试这个:

    WHERE
    
    CASE 
        WHEN (@ItemFor='' AND @ItemTo='') THEN 1
        WHEN (id between @ItemFor and @ItemTo) THEN 1
        WHEN (@CodeFrom='' and @CodeTo='') THEN 1
        WHEN (code between @CodeFrom and @CodeTo) THEN 1
        ELSE 0
    END = 1
    

    【讨论】:

    • 感谢您的解决方案
    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 2014-09-08
    • 2012-01-07
    • 2021-03-14
    • 2020-03-26
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多