plsql 检查 where 子句中至少一个变量不为空

Posted

技术标签:

【中文标题】plsql 检查 where 子句中至少一个变量不为空【英文标题】:plsql check at least one variable is not null inside where clause 【发布时间】:2014-08-13 08:31:48 【问题描述】:

我想根据两个变量过滤列,即(在伪代码中):

A如果第 1 列和第 2 列不为空,则同时过滤 filter1 和 filter2,否则 B如果第1列不为空,则对filter1进行过滤,否则 C 如果第 2 列不为空,则在 filter2 上进行过滤

我尝试过以下 PL/SQL 语句:

select * from table t where 
((t.column1 is not null and t.column1=filter1 and t.column2 is not null and t.column2=t.filter2) -- condition A
 or (t.column1 is not null and t.column1=filter1) -- condition B
 or (t.column2 is not null and t.column2=filter2)); -- condition C

虽然我已经检查过它是否适用于每个条件,但它并不适用于所有三个条件。 例如:

如果只有条件 A,则有效, 或者只有条件 B 和 C 有效。 但这不适用于条件 A、B 和 C。

怎么了?请帮忙:)

【问题讨论】:

@JoseRuiSantos 提出的解决方案有效,虽然我仍然不知道为什么我的第一次(有点太复杂)尝试没有!干杯 【参考方案1】:

当它们为空时,你应该换个思路:

select *
  from table t
 where (t.column1 is null or t.column1=filter1)
       and
       (t.column2 is null or t.column2=filter2);

考虑这种情况:

(t.column1 is null or t.column1=filter1)

如果t.column1 is null 为真,则甚至不会评估t.column1=filter1,因为true or whatever 始终为true。这意味着,仅当 t.column1 不为空时才会评估 t.column1=filter1


让我们测试每种情况。

column1 = null,column2 = null 查询返回所有行,因为条件是where (true or t.column1=filter1) and (true or t.column2=filter2),简化为where true and true

column1 = null, column2 != null 条件为where (true) and (false or t.column2=filter2),简化为where t.column2=filter2

column1 != null,column2 = null 条件为where (false or t.column1=filter1) and (true),简化为where t.column1=filter1

column1 != null,column2 != null 条件为where (false or t.column1=filter1) and (false or t.column2=filter2),简化为where t.column1=filter1 and t.column2=filter2

【讨论】:

谢谢,它有效:) 我理解你的解释,虽然我仍然不明白为什么我的初始条件不起作用。如果我对他们使用你的测试,这也应该验证? 它也应该验证,但要保持简单。在我看来,我做的方式更直观。【参考方案2】:

试试这个:

select *
  from table t
 where ((t.column1 = filter1 and t.column2 = t.filter2) -- condition 1
       or (t.column1 = filter1 and t.column2 is null )  -- condition 2
       or (t.column2 = filter2 and t.column1 is null)); -- condition 3

filters 值不能为空,否则你必须像下面这样使用 nvl:

select *
  from table t
 where ((t.column1 = nvl(filter1,-1) and t.column2 = nvl(t.filter2, -1) ) -- condition 1
       or (t.column1 = nvl(filter1,-1) and t.column2 is null )            -- condition 2
       or (t.column2 = nvl(filter2,-1) and t.column1 is null));           -- condition 3

【讨论】:

将 -1 替换为您想要的任何其他值,例如 nvl(filter1, 'null value') 对不起,我删除了我之前的评论,因为我意识到这不是问题,正如你所指出的那样。

以上是关于plsql 检查 where 子句中至少一个变量不为空的主要内容,如果未能解决你的问题,请参考以下文章

在 where 子句的 Case 语句中定义一个变量

sql不允许在where子句比较中使用case变量[重复]

如何在 Ruby 中使用 Where 子句 (PostgreSQL) 中的变量编写查询

如何在触发器中检查 where 子句中给出的内容?

如何仅使用在不使用动态SQL的情况下检查的复选框,将WHERE子句设置为在多个位列上进行过滤?

Psycopg2 - 在 where 子句中传递变量