如何在SQL WHERE子句中包含条件OR语句



在我的SQL语句中,如果Type的值等于'T',那么我想添加一个条件OR子句,如下所示。否则,将没有OR子句

if type not equal to 'T':
select customerid, type from customer
where cityid = '20' 
if type is equal to 'T'
select customerid, type from customer
where cityid = '20' OR cityid = '5'

可以使用case语句。想想每一个"何时"。作为你的if语句;之后,您可以添加where语句逻辑。

SELECT
customerid,
type
FROM customer
WHERE 
1 = CASE
WHEN type <> 'T' AND cityid = '20' THEN 1 -- not equal to 'T'
WHEN type = 'T' AND (cityid = '20' OR cityid = '5') THEN 1 -- type is equal to 'T'
ELSE 0 
END

使用布尔逻辑:

select customerid, type from customer
where cityid = '20' or
(cityid = '5' and type = 'T')

我建议您避免在where子句中使用case表达式。它们阻碍了优化。

看起来你在重构一个存储过程。

假设type是一个存储过程变量或参数,而不是customer表中的一列,我将这样写:

select c.customerid,
c.type
from customer c
where 1 = case coalesce( @type, '' )
when 'T' then case when c.cityid in ('20', '5') then 1 else 0 end
else          case when c.cityid in ('20'     ) then 1 else 0 end
end

针对@type的测试被封装在coalesce()函数中,因为null没有通过任何测试,除了显式的null测试。

我在这里使用case表达式,因为它使事情更表格化,当你需要添加一个新的情况下,当@type是'Z'…这只是一个额外的when条款。并且避免了andor之间操作符优先级的混淆。

首先,它假设你写的type是指@type

您总是可以使用OR来组合这种类型的逻辑,例如

select customerid, @type
from customer
where
-- Condition from first branch
(@type != 'T' and cityid = '20')
-- Condition from second branch
or (@type = 'T' and (cityid = '5' or cityid = '20'));

要特别小心你的括号,以确保你得到所需的逻辑。

注意:运算符优先级,即ANDOR之前求值,因此使用括号。

可以简化为:

select customerid, @type
from customer
where cityid = '20'
or (
cityid = '5' and @type = 'T'
);

然而,OR有一个导致性能问题的坏习惯,如果发生这种情况,你可以使用union all代替,例如

select customerid, @type
from customer
where @type != 'T' and cityid = '20'
union all
select customerid, @type
from customer
where @type = 'T' and (cityid = '5' or cityid = '20');

其他人建议在where子句中使用case,但这样做有可能使其不可sargable,即无法使用索引,而且在我看来,它更难阅读。在我看来,学习使用复杂的逻辑表达式是最好的。

相关内容

  • 没有找到相关文章

最新更新