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 子句中至少一个变量不为空的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Ruby 中使用 Where 子句 (PostgreSQL) 中的变量编写查询