【问题标题】:EXCEPT command - Find sailors who’ve reserved all boatsEXCEPT 命令 - 查找已预订所有船只的水手
【发布时间】:2017-01-09 18:20:12
【问题描述】:

我正在阅读一本教科书,但我不明白这个查询: 查找预订了所有船只的水手。

  • 我们有 3 个表:
    1. 水手:sid、sname、等级、年龄(主要:sid)
    2. 船:出价(主要:出价)
    3. 储备:sid,bid,day(primary,sid,bid,day)(sid 是水手的外键,bid 是船的外键)

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

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 时,它显示我有语法错误,除了

  2. 除了上面书中给出的解决方案,还有没有其他方法可以查询:查找已预订所有船只的水手

谢谢,

【问题讨论】:

  • except 在 MySQL 中无效。您可以在 SQL Server 中使用它。
  • 可以将except改写成NOT EXISTS()
  • 你甚至可以把它改写成NOT IN():stackoverflow.com/q/26697519/905902

标签: mysql sql relational-division not-exists sql-except


【解决方案1】:

您可以使用 COUNT 和 CONCAT 来执行此操作。此查询选择与船表中的每艘船配对(在 Reserves 表中)的水手:

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

【讨论】:

    【解决方案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));
    

    【讨论】:

      【解决方案3】:

      应使用以下查询:

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

      【讨论】:

      • 这行不通。 WHERE 子句分别查看每条记录。这个 [r.bid=ALL (SELECT b.bid FROM boats b);] 是说这个单独的 r.bid 等于船上的每个 b.bid。对于 2 艘或更多艘独特的船,这始终是错误的。
      猜你喜欢
      • 2021-02-27
      • 1970-01-01
      • 2016-05-18
      • 1970-01-01
      • 1970-01-01
      • 2019-04-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多