在我的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
条款。并且避免了and
和or
之间操作符优先级的混淆。
首先,它假设你写的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'));
要特别小心你的括号,以确保你得到所需的逻辑。
注意:运算符优先级,即AND
在OR
之前求值,因此使用括号。
可以简化为:
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,即无法使用索引,而且在我看来,它更难阅读。在我看来,学习使用复杂的逻辑表达式是最好的。