如何在 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'

解决方法

首先假设你写的 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 PrecedenceANDOR 之前进行评估,因此是括号。

这可以简化为:

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 子句。并且它避免了围绕 andor 之间的运算符优先级可能出现的混淆。

,

使用布尔逻辑:

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,),); 
}