简体   繁体   English

使用Like运算符的Where子句中的CASE语句

[英]CASE Statement in Where clause using Like Operator

I am facing an issue using CASE expression in where clause, To my knowledge syntax is correct but getting a error. 我在where子句中使用CASE表达式遇到一个问题,据我所知语法是正确的但出现错误。 Below is my code: 下面是我的代码:

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

Above code looks correct to me but I am getting syntax error saying 上面的代码对我来说似乎正确,但是我收到语法错误的提示

Incorrect syntax near the keyword 'like'. 关键字“喜欢”附近的语法不正确。

Edit 编辑

I have 4 sets of parameters and all need to go to where clause and all are string values: 我有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

You don't need a case expression for this. 您不需要为此使用case表达式。 Just do: 做就是了:

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

Your version doesn't work because SQL Server doesn't have boolean variables. 您的版本不起作用,因为SQL Server没有布尔变量。 Your a case expression is trying to return a boolean expression, but such an expression is not a value. 您的case表达式试图返回布尔表达式,但是这样的表达式不是值。

By the way, you probably intend: 顺便说一句,您可能打算:

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

This allows you to set only one of the limits. 这使您只能设置其中一个限制。

You could simplify and use this condition: 您可以简化并使用以下条件:

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)

and now syntax is correct. 现在语法正确。

Moreover, id like '%' and Code like '%' make no sense, because they are always true. 而且, id like '%'Code like '%'毫无意义,因为它们始终是真实的。 They can be read as "check if id (or Code ) is anything", so they can (should) be removed. 它们可以理解为“检查id (或Code )是否为任何东西”,因此可以(应该)将其删除。

This may solve your problem: 这可以解决您的问题:

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))

Since CASE cannot return a boolean value, you'll have to return something else and compare: 由于CASE无法返回布尔值,因此您必须返回其他值并进行比较:

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

Try this approach instead. 请尝试这种方法。

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

Doing the same as your case case statement. 与您的案例陈述相同。 If both variables are empty, then don't filter the ID clause. 如果两个变量都为空,则不要过滤ID子句。 If the variables are populated, check the ID within range 如果已填充变量,请检查范围内的ID

Note that if you are doing multiple conditions, I would suggest adding extra parenthesis, such as 请注意,如果您要同时执行多个条件,建议您添加额外的括号,例如

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

etc 等等

To explain what's wrong with the CASE WHEN. 解释CASE WHEN的问题。

A CASE WHEN returns a value, which you can choose depending on different criteria. “ CASE WHEN”返回一个值,您可以根据不同的条件选择该值。
And it returns a value based on the first criteria that matches. 并且它根据匹配的第一个条件返回一个值。
Hence, it's not supposed to return a criteria. 因此,它不应该返回条件。

The example below makes use of that. 下面的示例利用了这一点。

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

That said, regarding this example. 就是说,关于这个例子。
A solution that doesn't use a CASE WHEN in the WHERE clause, is probably the better approach. 在WHERE子句中不使用CASE WHEN的解决方案可能是更好的方法。

Example: 例:

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))

Because it's harder for the query optimizer to choose the fastest execution plan based on a CASE WHEN. 因为查询优化器很难根据CASE WHEN选择最快的执行计划。

Try this: 尝试这个:

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

i guess your mistake area 我猜你错了

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

you can try below way 你可以尝试下面的方式

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM