EXCEPT 命令 - 查找预订了所有船只的水手

EXCEPT command - Find sailors who’ve reserved all boats

我正在看课本,我不明白这个查询: 查找已预订所有船只的水手。

对于查询,查找预订了所有船只的水手,给出的答案是:

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

我的问题是:

  1. 上面的查询有问题吗?当我把它放入 MySQL Workbench 时,它显示我有 EXCEPT

  2. 的语法错误
  3. 除了上面书上给出的解法,还有没有其他的查询方式:查找预定了所有船的水手

谢谢,

您可以使用 COUNT 和 CONCAT 来执行此操作。此查询选择与船 table:

中的每艘船配对(在储备 table 中)的水手
SELECT Sailors.name
FROM Sailors INNER JOIN
(SELECT Reserves.sid
 FROM Reserves
 GROUP BY Reserves.sid
 HAVING COUNT(DISTINCT CONCAT(Reserves.sid, Reserves.bid)) =
 (SELECT COUNT(DISTINCT Boats.bid)
  FROM Boats)) sub
ON Sailors.sid = sub.sid

此处测试:http://sqlfiddle.com/#!9/82005/2

有时我看到 EXCEPT 由于与安装的 MySql 版本不兼容而无法工作。以下是可以使用 NOT EXISTS.

代替您的查询
SELECT S.sname 
FROM Sailors S
WHERE NOT EXISTS (SELECT B.bid 
                  FROM Boats B
                  WHERE NOT EXISTS(SELECT R.bid
                                   FROM Reserves R
                                   WHERE R.bid = B.bid
                                         AND R.sid = S.sid));

应使用以下查询:

SELECT sname FROM Sailors s ,Reserves r WHERE  s.sid=r.sid AND r.bid=ALL(SELECT b.bid FROM boats b);