我遇到了一个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。是对还是错?
谢谢
答案 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_VALUE
和5000
作为独立于PcsTable
的常量,并返回提供的true
PdsTable
具有匹配的值。
答案 2 :(得分:0)
我将按以下方式读取查询:
从pds
中获取所有在{{1}中不存在不存在的ACCT_NUM
的行 ,对于具有pct
且具有 ACCT_NUM
中的存在获取除pct
之外的所有行。
说明
1)如果PDS.OPT_VALUE = 5000
中不存在ACCT_NUM
中的pds
,则子查询无法返回行,因此pct
为NOT 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
结果是相同的。