Where 子句中使用 Like 运算符的 CASE 语句
CASE Statement in Where clause using Like Operator
我在 where 子句中使用 CASE 表达式时遇到问题,据我所知,语法是正确的,但出现错误。下面是我的代码:
Where
CASE
WHEN (@ItemFor='' and @ItemTo='')
THEN id like '%'
ELSE id between @ItemFor and @ItemTo
END
上面的代码在我看来是正确的,但我收到语法错误
Incorrect syntax near the keyword '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
您不需要 case
表达式。只要做:
where ((@ItemFor = '' and @ItemTo = '') or
id between @ItemFor and @ItemTo
)
您的版本不工作,因为SQL服务器没有布尔变量。您的 case
表达式试图 return 布尔表达式,但这样的表达式不是值。
顺便说一句,您可能打算:
where (id >= @itemfrom or @itemfrom = '') and
(id <= @itemto or @itemto = '')
这允许您仅设置一个限制。
因为 CASE 不能 return 布尔值,你必须 return 其他东西并比较:
WHERE
CASE
WHEN Condition1 THEN 1
WHEN Condition2 THEN 0
WHEN Condition3 THEN 1
ELSE 0
END = 1
试试这个方法。
where (@itemFor='' and @itemto='') OR (id between @itemFor and @itemto)
与您的 case case 语句相同。如果两个变量都为空,则不要过滤 ID 子句。如果填充了变量,请检查范围内的 ID
注意,如果你做多个条件,我会建议添加额外的括号,例如
where ( (@itemFor='' and @itemto='') OR (id between @itemFor and @itemto) )
and (firstName like '%JOE%')
等等
试试这个:
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
我猜你的错误区域
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
解释 CASE WHEN 有什么问题。
A CASE WHEN return是一个值,您可以根据不同的条件进行选择。
它 return 是一个基于匹配的第一个条件的值。
因此,它不应该 return 一个标准。
下面的示例使用了它。
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 选择最快的执行计划。
您可以简化并使用这个条件:
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 '%'
没有任何意义,因为它们始终为真。它们可以读作 "check if id
(or Code
) is anything",因此可以(应该)删除它们。
这可能会解决您的问题:
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))
我在 where 子句中使用 CASE 表达式时遇到问题,据我所知,语法是正确的,但出现错误。下面是我的代码:
Where
CASE
WHEN (@ItemFor='' and @ItemTo='')
THEN id like '%'
ELSE id between @ItemFor and @ItemTo
END
上面的代码在我看来是正确的,但我收到语法错误
Incorrect syntax near the keyword '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
您不需要 case
表达式。只要做:
where ((@ItemFor = '' and @ItemTo = '') or
id between @ItemFor and @ItemTo
)
您的版本不工作,因为SQL服务器没有布尔变量。您的 case
表达式试图 return 布尔表达式,但这样的表达式不是值。
顺便说一句,您可能打算:
where (id >= @itemfrom or @itemfrom = '') and
(id <= @itemto or @itemto = '')
这允许您仅设置一个限制。
因为 CASE 不能 return 布尔值,你必须 return 其他东西并比较:
WHERE
CASE
WHEN Condition1 THEN 1
WHEN Condition2 THEN 0
WHEN Condition3 THEN 1
ELSE 0
END = 1
试试这个方法。
where (@itemFor='' and @itemto='') OR (id between @itemFor and @itemto)
与您的 case case 语句相同。如果两个变量都为空,则不要过滤 ID 子句。如果填充了变量,请检查范围内的 ID
注意,如果你做多个条件,我会建议添加额外的括号,例如
where ( (@itemFor='' and @itemto='') OR (id between @itemFor and @itemto) )
and (firstName like '%JOE%')
等等
试试这个:
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
我猜你的错误区域
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
解释 CASE WHEN 有什么问题。
A CASE WHEN return是一个值,您可以根据不同的条件进行选择。
它 return 是一个基于匹配的第一个条件的值。
因此,它不应该 return 一个标准。
下面的示例使用了它。
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 选择最快的执行计划。
您可以简化并使用这个条件:
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 '%'
没有任何意义,因为它们始终为真。它们可以读作 "check if id
(or Code
) is anything",因此可以(应该)删除它们。
这可能会解决您的问题:
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))