问题描述
在我的 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'
解决方法
首先假设你写的 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'));
对括号格外小心,以确保获得所需的逻辑。
注意:Operator Precedence 即 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,即无法使用索引,并且在我看来它更难阅读。学习使用复杂的逻辑表达式是最好的 IMO。
看起来您正在重构一个存储过程。
假设 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
未通过任何测试,但显式测试无效。
我在这里也使用了 case
表达式,因为它使事情更加表格化,并且当您需要为 @type
是 ' 时添加新案例时Z'...它只是一个额外的 when
子句。并且它避免了围绕 and
和 or
之间的运算符优先级可能出现的混淆。
使用布尔逻辑:
select customerid,type from customer
where cityid = '20' or
(cityid = '5' and type = 'T')
我建议您避免在 case
子句中使用 where
表达式。它们会阻碍优化。
您可以使用 case 语句。将每个“何时”视为您的 if 语句;之后,您可以添加 where 语句逻辑。
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: SafeaArea(
child: Container(
height: MediaQuery.of(context).size.height,padding: const EdgeInsets.all(20),// small padding to improve the UI
child: TextField(
maxLines: 100,keyboardType: TextInputType.multiline,),);
}