两个不同的表之间不存在

时间:2018-12-29 07:54:09

标签: sql oracle

我遇到了一个SQL查询,该查询在如下所示的两个不同表之间执行不存在。

SELECT PDS.FILE_SUBID
       PDS.ACCT_NUM
       PDS.VALUE
  FROM PdsTable PDS

 WHERE NOT EXISTS (SELECT PCS.ACCT_NUM FROM
        PcsTable PCS
        WHERE PDS.ACCT_NUM = PCS.ACCT_NUM
        AND PDS.OPT_VALUE = 5000
        )

我了解何时发生WHERE PDS.ACCT_NUM = PCS.ACCT_NUM时,SQL引擎必须执行INNER JOIN才能从两个表中获取相似的ACCT_NUM,但是内部查询中的该参数(PDS.OPT_VALUE)又如何呢?此列甚至不存在于PcsTable表中。

请问这个查询或这种逻辑在sql中如何工作?

我的假设说:在内部查询中使用PDS.OPT_VALUE = 5000之前,应先应用内部联接类型的条件,例如WHERE PDS.ACCT_NUM = PCS.ACCT_NUM。是对还是错?

谢谢

3 个答案:

答案 0 :(得分:1)

请注意,NOT EXISTS IN不是有效的SQL,因此我假设IN是一个错字。

该查询在NOT EXISTS时说“覆盖” PDS.OPT_VALUE = 5000比较。也就是说,在这种情况下,该记录自动不存在。

您可以这样写:

SELECT PDS.FILE_SUBID, PDS.ACCT_NUM, PDS.VALUE
FROM PdsTable PDS
WHERE NOT EXISTS (SELECT 1
                  FROM PcsTable PCS
                  WHERE PDS.ACCT_NUM = PCS.ACCT_NUM
                 ) OR
      PDS.OPT_VALUE = 5000; -- <<< this predicate is very probably wrong and should be: nvl(PDS.OPT_VALUE,0) != 5000 

查询的逻辑非常混乱。如果为opt_value = 5000,则子查询不返回任何行。并且,not exists将返回外部记录。不管是否匹配。

我发现此版本更加清晰。我不喜欢在子查询中放置这样的条件。我认为它们使理解变得更加困难。

答案 1 :(得分:0)

它们都是返回布尔逻辑的逻辑语句。 PDS.ACCT_NUM = PCS.ACCT_NUM返回true时,PDS.OPT_VALUE = 5000也返回true,并将它们与and组合在一起,这意味着两个条件都同时返回true时间。因此,子查询返回true

就像查询在子查询中使用PDS.ACCT_NUM一样,它也使用PDS.OPT_VALUE5000作为独立于PcsTable的常量,并返回提供的true PdsTable具有匹配的值。

答案 2 :(得分:0)

我将按以下方式读取查询:

pds中获取所有在{{1}中不存在不存在的ACCT_NUM的行 ,对于具有pct且具有 ACCT_NUM中的存在获取除pct之外的所有行。

说明

1)如果PDS.OPT_VALUE = 5000中不存在ACCT_NUM中的pds,则子查询无法返回行,因此pctNOT EXISTS

2)如果{{1}中存在true中的ACCT_NUM,则第一个谓词为true,因此第二个谓词为pds 一定不能为真,以便子查询不返回任何行。

因此,基本上,您使用pct和所有其他值(包括NULL)进行了 filter 行。

小例子

PDS.OPT_VALUE = 5000

PDS.OPT_VALUE = 5000传递了所有行,其中2行不在create table pds as select 1 acct_num, 4999 OPT_VALUE from dual union all select 1 acct_num, 5000 OPT_VALUE from dual union all select 1 acct_num, null OPT_VALUE from dual union all select 2 acct_num, null OPT_VALUE from dual; create table pcs as select 1 acct_num from dual; select * from pds where NOT EXISTS (SELECT PCS.ACCT_NUM FROM PCS WHERE PDS.ACCT_NUM = PCS.ACCT_NUM AND PDS.OPT_VALUE = 5000 ) order by 1,2; ACCT_NUM OPT_VALUE ---------- ---------- 1 4999 1 2

ACCT_NUM=2 OPT 4999和NULL通过,但在PCS中将5000过滤为1。

重新构造查询将第二个谓词从子查询中推出更为清楚:

ACCT_NUM=1

结果是相同的。