Oracle -具有空值条件的Where子句未给予相应结果

b1uwtaje  于 2023-08-03  发布在  Oracle
关注(0)|答案(2)|浏览(180)

Oracle RDBMS:18C
我这里有一个样本数据。
https://dbfiddle.uk/qbB_JLRp .

我想根据with-clause中的条件得到ColD,E,F结果。ColA、COLB和COLC。


ColA、B、C条件字符串由用户选择。所以它可能会不时地改变。(我使用vba userform来收集用户的选择,并通过vba生成一个with子句字符串,所以不用担心动态with子句字符串)
我的问题是当with子句中的条件字符串有''值时,如何得到正确的结果?(以橙子笔刷突出显示)

我尝试将with-clause中的''更改为null,但不起作用。当with-clause中存在空值条件时,未检索到相应的行。例如,with-clause中的condition 2应该已经检索到下面的3条记录。



似乎每个空值条件都必须像下面这样特别指定,以获得正确的结果。
x1c4d 1x的
这样一来,where-clause就会变得很长很复杂,因为我必须在where-clause中特别指定每个空值条件,只要with-clause中有一个。
希望我的表达清楚。如果有一种方法可以解决-clause并对where-clause做一些调整,我将非常感激。
'--------------------------------------
根据**@The Impaler的回答,我对'IS NOT DISTINCT FROM'运算符进行了更深入的挖掘。Google的第一个结果很好地解释了为什么我的原始查询不能处理Null值。(可能“in”运算符正在使用equal**比较运算符。)
以下是Google搜索结果中的“IS NOT DISTINCT FROM”运算符:



希望这个谷歌结果能帮助像我这样需要更具体解释的人。

pvabu6sv

pvabu6sv1#

您正在查找SQL标准的IS NOT DISTINCT FROM运算符,不幸的是,Oracle中没有实现该运算符。然而,它可以用DECODE()来模拟。
例如,您可以执行以下操作:

with Desired_Column_Combination as (
  Select 'A1' ColA,'B2' ColB,'C2' ColC from dual union all 
  Select 'A1' ColA,'B1' ColB,'' ColC from dual union all --Should've 3 records
  Select 'A2' ColA,'' ColB,'C3' ColC from dual union all --Should've 2 records
  Select 'A3' ColA,'B1' ColB,'C1' ColC from dual
)
select * 
from SampleTable S
where exists (
  select 1
  from Desired_Column_Combination d
  where decode(s.ColA, d.ColA, 1, 0) = 1
    and decode(s.ColB, d.ColB, 1, 0) = 1
    and decode(s.ColC, d.ColC, 1, 0) = 1
);

字符串
测试结果:

COLA  COLB  COLC  DESIRED_COLD  DESIRED_COLE  DESIRED_COLF 
 ----- ----- ----- ------------- ------------- ------------ 
 A1    B1    null  28            24            23           
 A1    B1    null  13            90            36           
 A1    B1    null  27            27            82           
 A1    B2    C2    54            58            34           
 A2    null  C3    22            27            12           
 A2    null  C3    14            78            50           
 A3    B1    C1    44            70            53           
 A3    B1    C1    38            13            11


参见db<>fiddle上的运行示例。

wfveoks0

wfveoks02#

你需要记住“NULL不等于任何东西-甚至不等于它本身”。
从Fiddle中借用和调整代码:

With Desired_Column_Combination as (
-- Select 'A1' ColA,'B2' ColB,'C2' ColC from dual union all 
Select 'A1' ColA,'B1' ColB, null ColC from dual -- union all --Should've 3 records
-- Select 'A2' ColA,'' ColB,'C3' ColC from dual -- union all --Should've 2 records
-- Select 'A3' ColA,'B1' ColB,'C1' ColC from dual
  )
Select * from SampleTable S
where (ColA,ColB,ColC) 
  in (Select ColA,ColB,ColC from Desired_Column_Combination)
union all
Select * from SampleTable S
where (ColA,ColB) 
  in (Select ColA,ColB from Desired_Column_Combination)
 and ColC is null
union all
Select * from SampleTable S
where (ColA,ColC) 
  in (Select ColA,ColC from Desired_Column_Combination)
 and ColB is null

字符串
returns three rows的数据。

With Desired_Column_Combination as (
-- Select 'A1' ColA,'B2' ColB,'C2' ColC from dual union all 
-- Select 'A1' ColA,'B1' ColB, null ColC from dual -- union all --Should've 3 records
Select 'A2' ColA,'' ColB,'C3' ColC from dual -- union all --Should've 2 records
-- Select 'A3' ColA,'B1' ColB,'C1' ColC from dual
  )
Select * from SampleTable S
where (ColA,ColB,ColC) 
  in (Select ColA,ColB,ColC from Desired_Column_Combination)
union all
Select * from SampleTable S
where (ColA,ColB) 
  in (Select ColA,ColB from Desired_Column_Combination)
 and ColC is null
union all
Select * from SampleTable S
where (ColA,ColC) 
  in (Select ColA,ColC from Desired_Column_Combination)
 and ColB is null


returns two rows
因此,您需要在Desired_Column_Combination的选择中适当地满足NULL值。
如果需要调整/进一步详细说明,请予以说明。

相关问题