【问题标题】:mysql subqueries keeps repeatingmysql子查询不断重复
【发布时间】:2020-03-12 11:24:48
【问题描述】:

大家好,我很难做这个查询,我需要列出 Marina 1 中每艘船的船名、船主编号、船主姓氏和船主名字。

我有一张 marina_slip 的桌子 和 marina_owner

我有代码

SELECT ms.boat_name, ms.owner_num, o.last_name, o.first_name
FROM marina_slip ms, owner o
WHERE o.owner_num IN(SELECT ms.owner_num FROM marina_slip ms WHERE marina_num = '1');

输出正确但重复

查询输出

【问题讨论】:

  • 您介意编辑您的问题并使用文本框上方的<> 按钮来格式化代码吗?
  • 你好,谢谢你的建议。对不起,我是这个社区的新手。还是个学生。
  • 另外,除非有人特别要求,否则请勿发布屏幕截图。您发布了文本输出的屏幕截图,a) 比复制/粘贴更费力,b) 搜索引擎无法搜索,c) 我们无法复制(如果我们想要为您的问题设置测试。我们更喜欢粘贴文本,而不是文本屏幕截图
  • 现在,对于您的问题 - 具体来说,您的输出不重复/不包含重复项。所有行都是唯一的。阅读“什么是笛卡尔积”,以便您更好地理解为什么它与您的期望不符

标签: mysql database subquery repeat


【解决方案1】:

您正在执行旧式连接,但没有连接条件。
使用带有 ON 子句的正确连接:

SELECT ms.boat_name, ms.owner_num, o.last_name, o.first_name
FROM marina_slip ms INNER JOIN owner o
ON o.owner_num = ms.owner_num
WHERE o.owner_num IN (SELECT ms.owner_num FROM marina_slip ms WHERE marina_num = '1'); 

或:

SELECT ms.boat_name, ms.owner_num, o.last_name, o.first_name
FROM marina_slip ms INNER JOIN owner o
ON o.owner_num = ms.owner_num
WHERE ms.marina_num = '1'; 

【讨论】:

    【解决方案2】:

    我们已经有 30 年没有做过这样的连接了:

    FROM marina_slip ms, owner o
    

    主要是因为它鼓励了你现在看到的问题; marina_slip 的每一行都与所有者的每一行合并。此处表达的表之间没有关系。使用现代连接语法不会有问题:

    SELECT ms.boat_name, ms.owner_num, o.last_name, o.first_name
    FROM 
      marina_slip ms
    
      --express the relationship between the tables. -> owner num in each table is equal 
      INNER JOIN owner o ON o.owner_num = ms.owner_num
    
    WHERE ms.marina_num = '1'; 
    

    see this other questionjeff atwood's coding blog 了解有关如何使用 INNER/LEFT/RIGHT JOIN 语法的更多信息

    【讨论】:

    • 我遵循的语法来自我大学的书,我认为它已经过时了。谢谢你们的帮助。
    • 是的,绝对是向你的大学投诉的人。出于好奇,这是什么书?
    【解决方案3】:

    你的桌子之间没有关节。

    您可以通过LEFT JOIN 完成此操作

    SELECT * FROM marina_slip
    LEFT JOIN owner ON owner.owner_num=marina_slip.owner_num
    WHERE marina_num=1
    

    或者,如果您想使用您的选择,请在 WHERE 子句中添加 ms.owner_num=o.owner_num

    SELECT *
    FROM marina_slip ms, owner o
    WHERE ms.owner_num=o.owner_num
        AND o.owner_num IN(SELECT ms.owner_num FROM marina_slip ms WHERE marina_num = '1');
    

    dbfiddle demo

    【讨论】:

    • 为什么是左连接?有什么区别吗?
    • 使用INNER JOIN,您只有拥有船主的船。使用LEFT JOIN,即使他们没有所有者,您也可以拥有所有船只
    • 所有船只都有主人。
    • 在这种情况下,不要忘记将owner_num的外键添加到marina_slip表中
    猜你喜欢
    • 1970-01-01
    • 2015-12-21
    • 2014-05-31
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    相关资源
    最近更新 更多