以下查询应该返回“保留所有船只的水手”
这是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”后面的子查询应返回Boats表中所有记录的船ID(bid)。因此,接下来的查询应该返回所有已预留的船只的船只ID ...这意味着如果有人保留所有船只,则不应返回任何内容,这意味着NOT EXISTS将评估为真,它将只是给那个水手的名字?我认为这是让我困惑的最后一部分...它最终如何归还水手的名字?
答案 0 :(得分:1)
我们有一些可以由水手保留的船只,水手已经注册并且我们知道它们,所以表格的结构是:
[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;
当你需要知道水手没有(永远)保留哪些船只时;您可以使用以下查询,为您提供出价=> [1,3]为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
会返回左输入查询中不是由右输入查询输出的不同行。
EXISTS
:指定要测试行是否存在的子查询。
答案 1 :(得分:0)
您可以转换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
的船只的水手,这与那些预留了所有船只的船员相同#34;