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

时间:2018-07-27 11:07:24

标签: sql sql-server tsql where-clause

我在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

8 个答案:

答案 0 :(得分:5)

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

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

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

顺便说一句,您可能打算这样做:

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

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

答案 1 :(得分: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)是否是任何东西,以便可以(应该)将其删除。

答案 2 :(得分:2)

这可以解决您的问题:

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

尝试这种方法。

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

答案 5 :(得分:1)

解释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选择最快的执行计划。

答案 6 :(得分:0)

尝试一下:

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

答案 7 :(得分:0)

我猜你的错误区域

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