真的很难理解这个查询

Really hard time understanding this query

下面的查询应该是 return "sailors who have reserved all boats"

这是 mySQL 代码

SELECT S.sname
FROM Sailors S
WHERE NOT EXISTS 
    ((SELECT B.bid  
     FROM Boats B)
    Except
    (SELECT R.bid  
     FROM Reserves R
     WHERE R.sid = S.sid))

而我只是……不知道如何通读它。我知道 "NOT EXISTS" 之后的子查询应该 return 船 table 上所有记录的船 ID(出价)。因此,Except 后面的查询应该是 returning 所有已预订船只的船 ID...所以这意味着如果有人预订了所有船只,则不应 return,这意味着NOT EXISTS 将评估为真,它只会给出那个水手的名字?我认为这是让我感到困惑的最后一部分……它是如何结束 return 水手的名字的?

你可以转换sql,subselect

(SELECT B.bid  
 FROM Boats B)
Except
(SELECT R.bid  
 FROM Reserves R
 WHERE R.sid = S.sid)

应该和

一样
(SELECT B.bid  
 FROM Boats B
 WHERE B.sid <> S.sid)

如果您替换主 sql 中的部分,您将得到

SELECT S.sname
FROM Sailors S
WHERE NOT EXISTS 
(SELECT B.bid  
 FROM Boats B
 WHERE B.sid <> S.sid)

Select 只有那些没有其他 sid 船的水手存在,这与 "sailors who have reserved all boats"

相同

我们有一些船可以由水手预订,水手已经注册并且我们知道他们,所以表的结构是:

[Table: Boats]          [Table: Sailors]        [Table: Reserves]
+-----+--------+        +-----+----------+      +-----+-----+-----+
| bid | bname  |        | sid | sname    |      | rid | bid | sid |
+-----+--------+        +-----+----------+      +-----+-----+-----+
| 1   | Boat 1 |        | 1   | Sailor 1 |      | 1   | 1   | 1   |
| 2   | Boat 2 |        | 2   | Sailor 2 |      | 2   | 2   | 3   |
| 3   | Boat 3 |        | 3   | Sailor 3 |      +-----+-----+-----+
+-----+--------+        +-----+----------+

在上面的数据中,你需要知道哪些船没有预定;你可以使用下面的查询来给你出价 => 3:

SELECT B.bid  FROM Boats B
EXCEPT
SELECT R.bid  FROM Reserves R;

当你需要知道哪些船没有(从来)没有被水手预订时;你可以使用下面的查询,它会给你 bid => [1, 3] for sid = 3:

SELECT B.bid  FROM Boats B
EXCEPT
SELECT R.bid  FROM Reserves R  WHERE R.[sid] = 3;

当一个水手预订了所有的船时,上面的查询将没有结果,所以 NOT EXISTS(<above query>) 将为真。现在您可以使用上面的查询来找到保留所有船只的水手,如下所示:

SELECT S.sname
FROM Sailors S
WHERE NOT EXISTS (
    SELECT B.bid  FROM Boats B
    EXCEPT
    SELECT R.bid  FROM Reserves R
    WHERE R.[sid] = S.[sid]);

所以如果Reserves的数据变成这样:

 [Table: Reserves]
 +-----+-----+-----+
 | rid | bid | sid |
 +-----+-----+-----+
 | 1   | 1   | 1   |
 | 2   | 2   | 1   |
 | 3   | 3   | 1   |
 +-----+-----+-----+

您的查询将给出 Sailor 1 ;) 的结果。


更多信息:
EXCEPT returns 来自左侧输入查询但右侧输入查询未输出的不同行。
EXISTS: 指定一个子查询来测试行的存在。