Mysql 真的很难理解这个问题

Mysql 真的很难理解这个问题,mysql,sql,nested-queries,Mysql,Sql,Nested Queries,下面的查询应该返回预订了所有船只的水手 下面是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)) 我只是…不知道怎么读。我知道下面的子查询notexists应该返回Boats表中所有记录的boatid

下面的查询应该返回预订了所有船只的水手

下面是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))

我只是…不知道怎么读。我知道下面的子查询notexists应该返回Boats表中所有记录的boatid bid。因此,接下来的查询应该返回所有已预订船只的船只ID…这意味着如果有人预订了所有船只,则不应返回任何内容,这意味着NOT EXISTS将计算为true,并只给出该海员的姓名?我想这是让我困惑的最后一部分…它怎么会最终返回水手的名字

您可以转换sql,子选择

(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)

仅选择那些不存在具有其他sid的船只的水手,这与保留所有船只的水手相同

我们有一些可以由水手保留的船只,水手是注册的,我们知道他们,因此表的结构为:

[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;
当你需要知道哪些船从来没有被水手保留;您可以使用以下查询,为sid=3提供bid=>[1,3]:

SELECT B.bid  FROM Boats B
EXCEPT
SELECT R.bid  FROM Reserves R  WHERE R.[sid] = 3;
当一名水手预订了所有船只时,上述查询将没有结果,因此notexists将为true。现在,您可以使用上面的查询找到保留所有船只的水手,如下所示:

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]);
 [Table: Reserves]
 +-----+-----+-----+
 | rid | bid | sid |
 +-----+-----+-----+
 | 1   | 1   | 1   |
 | 2   | 2   | 1   |
 | 3   | 3   | 1   |
 +-----+-----+-----+
因此,如果储量数据变成这样:

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]);
 [Table: Reserves]
 +-----+-----+-----+
 | rid | bid | sid |
 +-----+-----+-----+
 | 1   | 1   | 1   |
 | 2   | 2   | 1   |
 | 3   | 3   | 1   |
 +-----+-----+-----+
您的查询将给出sealer 1;的结果

更多信息: Exception从左输入查询返回右输入查询未输出的不同行。
EXISTS:指定一个子查询来测试行的存在性。

我不知道MySQL支持EXCEPTclause@Strawberry那很有趣。我的教授让我们下载MySQL服务器来练习SQL查询,但她给了我们类似这样的非MySQL示例。唉。@shA.t这是我的教授给我的问题。我更希望看到的是它所做的事情的英文翻译,而不是它的更正。我相信子查询会返回所有未保留的船ID。所以当我读到notexists时,notexists应用于什么?什么是不存在的?是不是说查找所有未保留的船ID表中不存在的sname?如果这个表本身没有snames,只有boat id,那么它是如何得到返回的任何名称的呢?下面将通读一遍,但在最后,当您定义EXCEPT时,它不应该说从左输入查询返回由右输入查询输出的不同行吗@沙。t@FrostyStraw好的,那么…以下任何一个是不正确的:不存在是不是一个接一个地应用到水手的每一行?例如,对于sid=1,它将执行“内部不存在”查询,如果没有返回行,它将只返回与该id匹配的水手的名称?然后它将转到sid=2,假设多个水手可以同时预订一艘船,如果没有返回行,那么将返回与sid=2匹配的水手名,否则它将继续转到sid=3,依此类推@沙蒂可以说是;DBMS离它如此之近;您可以通过手动设置外部值(如S.[sid];)的值来检查内部选择的有效性;。