2

I am reading a textbook and I do not understand this query: Find sailors who’ve reserved all boats.

  • We have 3 tables:
    1. Sailors: sid, sname, rating, age (primary: sid)
    2. Boats: bid (primary: bid)
    3. Reserves: sid, bid, day (primary, sid, bid, day) (sid is foreign key to sailors, bid is foreign key to boats)

For the query, Find sailors who’ve reserved all boats, the answer given is:

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

My questions are:

  1. Is there something wrong with the above query? When I put it into MySQL Workbench, it shows I have syntax error with the EXCEPT

  2. Beside the solution given by the book above, is there any other way to do the query: Find sailors who’ve reserved all boats

Thank you,

wildplasser
  • 43,142
  • 8
  • 66
  • 109
NNguyen
  • 113
  • 1
  • 6

3 Answers3

3

You can do this using COUNT and CONCAT. This query selects the sailors that are paired (in the Reserves table) with each boat in the boat 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

Tested here: http://sqlfiddle.com/#!9/82005/2

kjmerf
  • 4,275
  • 3
  • 21
  • 29
3

Sometime i have seen that EXCEPT don't work due to incompatibility with the installed version of MySql. Following is the query which can be used in place of yours using 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));
jack jay
  • 2,493
  • 1
  • 14
  • 27
0

The following query should be used:

SELECT sname FROM Sailors s ,Reserves r WHERE  s.sid=r.sid AND r.bid=ALL(SELECT b.bid FROM boats b);
Rann Lifshitz
  • 4,040
  • 4
  • 22
  • 42
  • This would not work. WHERE clauses look at each record individually. This [r.bid=ALL (SELECT b.bid FROM boats b);] is saying this individual r.bid is equal to every b.bid in boats. This is always false for 2 or more unique boats. – Aaron Elliot Jun 29 '21 at 01:41