【问题标题】:How do NOT EXISTS and correlated subqueries work internallyNOT EXISTS 和相关子查询如何在内部工作
【发布时间】:2018-12-15 05:48:06
【问题描述】:

我想了解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))

【问题讨论】:

    标签: sql correlated-subquery not-exists


    【解决方案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 上的示例。

    【讨论】:

      【解决方案2】:

      如果您在查询中看到双重嵌套的“不存在”,这通常表示正在执行关系除法(谷歌一下,您会发现很多东西)。

      将查询子句逐句翻译成非正式语言会产生如下内容:

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

      翻译成

      没有不服药的患者。

      翻译成

      服用所有药物的患者。

      关系除法是对应于谓词逻辑中的全称量化的关系代数算子。

      【讨论】:

      • 谢谢。我不知道这个“关系划分”。我会在周末花更多的时间和耐心来研究它。此外,你的非正式语言逻辑也会有很大帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 2017-06-06
      • 1970-01-01
      • 2020-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多