NOT EXISTS 和相关子查询如何在内部工作
How do NOT EXISTS and correlated subqueries work internally
我想了解 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))
您的查询试图找到:
服用所有药物的所有患者。
我重写了你的脚本,找到
所有未服用任何药物的患者。
-- 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 运算符解释为 "Specifies a subquery to test for the existence of rows"。
您还可以查看 docs.microsoft.com Here.
上的示例
如果您在查询中看到双重嵌套 "not exists",这通常表示正在执行关系划分(google,您会发现很多东西)。
将查询逐句翻译成非正式语言会产生如下内容:
获得患者
不存在
药物
不存在
该患者服用该药物的处方
转换为
没有不服药的患者。
转换为
服用所有药物的患者。
关系除法是谓词逻辑中对应全称量化的关系代数运算符。
我想了解 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))
您的查询试图找到:
服用所有药物的所有患者。
我重写了你的脚本,找到
所有未服用任何药物的患者。
-- 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 运算符解释为 "Specifies a subquery to test for the existence of rows"。
您还可以查看 docs.microsoft.com Here.
如果您在查询中看到双重嵌套 "not exists",这通常表示正在执行关系划分(google,您会发现很多东西)。
将查询逐句翻译成非正式语言会产生如下内容:
获得患者
不存在
药物
不存在
该患者服用该药物的处方
转换为
没有不服药的患者。
转换为
服用所有药物的患者。
关系除法是谓词逻辑中对应全称量化的关系代数运算符。