不存在和相关子查询在内部如何工作

时间:2018-07-06 15:17:52

标签: sql correlated-subquery not-exists

我想了解NOT EXISTS在相关子查询中的工作原理。

在此查询中,它返回了服用所有药物的患者,但我不明白为什么。

有人可以解释一下此查询执行的每个步骤中发生了什么,以及每个步骤中正在考虑和删除哪些记录。

create table medication
(
    idmedic INT PRIMARY KEY,
    name VARCHAR(20),
    dosage NUMERIC(8,2)
);

create table patient 
(
    idpac INT PRIMARY KEY,
    name VARCHAR(20)
);

create table prescription  
(
    idpac INT,
    idmedic INT,
    date DATE,
    time TIME,
    FOREIGN KEY (idpac) REFERENCES patient(idpac),
    FOREIGN KEY (idmedic) REFERENCES medication(idmedic)
);

insert into patient (idpac, name) 
values (1, 'joe'), (2, 'tod'), (3, 'ric');

insert into medication (idmedic, name, dosage) 
values (1, 'tilenol', 0.01), (2, 'omega3', 0.02);

insert into prescription (idpac, idmedic, date, time) 
values (1, 1, '2018-01-01', '20:00'), (1, 2, '2018-01-01', '20:00'),
       (2, 2, '2018-01-01', '20:00');

select 
    pa.name 
from 
    patient pa
where 
    not exists (select 1 from medication me
                where not exists (select 1
                                  from prescription pr
                                  where pr.idpac = pa.idpac 
                                    and pr.idmedic = me.idmedic))

2 个答案:

答案 0 :(得分:1)

您的查询正试图找到:
所有服用所有药物的患者

我已经重写了您的脚本以查找
所有未服用任何药物的患者

-- This returns 1 Row, patient ric  
-- all the patients who take all medications

select 
    pa.name 
from 
    patient pa
where 
    not exists (select 1 from medication me
                where /**** not ****/ exists (select 1
                                  from prescription pr
                                  where pr.idpac = pa.idpac 
                                    and pr.idmedic = me.idmedic))

演示:

Here是一个SQL Fiddle。

我认为此查询将向您阐明EXISTS运算符的用法。
如果不是,请尝试将子查询视为JOIN,而将EXISTS / NOT EXISTS视为WHERE条件。

EXISTS运算符解释为“指定子查询以测试行是否存在”。
您也可以在docs.microsoft.com Here上查看示例。

答案 1 :(得分:0)

如果您在查询中看到一个双重嵌套的“不存在”,这通常表明正在执行关系划分(谷歌可以找到很多东西)。

将查询子句按子句转换为非正式语言会产生类似以下内容:

找病人
不存在的
药物
  不存在的
  该患者服用该药的处方

翻译为

没有不服用药物的患者。

翻译为

服用所有药物的患者。

关系除法是与谓词逻辑中的通用量化相对应的关系代数算子。