【问题标题】:How does WHERE NOT EXISTS in this query work?此查询中的 WHERE NOT EXISTS 是如何工作的?
【发布时间】:2021-02-26 01:40:18
【问题描述】:

我有 3 张桌子,一张用于医生、病人和约会,如下所示

create table Doctors 
(
    Did int identity primary key,
    docName varchar (20),
    specialization varchar (20),
    salary decimal (8,2)
)

create table Patients
(
    Pid int identity primary key,
    fullName varchar (20)
)

create table Appointments
(
    datey DATETIME,
    pid int foreign key REFERENCES Patients(Pid),
    did int foreign key REFERENCES Doctors(Did),
    primary key (pid, did)
)

我正在尝试理解“获取已与所有患者预约的医生”的查询。这是查询:

SELECT D.docName
FROM Doctors D
WHERE NOT EXISTS (
    (
        SELECT P.Pid
        FROM Patients P
    )
    EXCEPT
    (
        SELECT A.pid
        FROM Appointments A
        WHERE A.did = D.Did
    )
)

我知道Where not Exists 之后的子查询部分正在查询所有当前没有医生预约的患者。我不明白的是,当它被提供给where NOT Exists 时,它会向我显示自从我使用 Visual Studio 代码中的一些数据运行子查询以来确实有预约的医生的姓名。查询结果为空。

那么where not exist 和一般查询在这种情况下是如何工作的呢?

谢谢。

【问题讨论】:

  • 一般比较常见的写成两个嵌套的NOT EXISTS,效果(和查询计划)是一样的,但是可能更容易阅读

标签: sql sql-server database relational-database


【解决方案1】:

这解释起来有点复杂。但这个想法是改写问题:

获取所有医生,确保没有没有与医生预约的患者。

即使英语是您的母语,所有这些负面因素也会使问题难以理解。这是表达您想要的另一种方式:“请与所有患者预约过的医生”。

步骤如下:

  • 第一个子查询获取所有患者。
  • 第二个子查询获取特定医生的所有患者。
  • EXCEPT 获取未与医生预约的患者列表。
  • 最后,如果没有,那么医生已经预约了所有患者。

相比之下,另一种使用聚合的方法似乎不言自明:

SELECT D.did, D.docName
FROM Doctors D JOIN
     Appointments A
     ON A.did = D.did
GROUP BY D.did, D.docName
HAVING COUNT(DISTINCT A.pid) = (SELECT COUNT(*) FROM Patients);

【讨论】:

  • 非常感谢。我现在明白了。正如您所提到的,聚合方法是一种更好的方法。
  • 不言自明,但不一定更快。 DoubleNOT EXISTS 是一种常用的关系除法方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-06
  • 2019-03-01
  • 2016-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多