【问题标题】:MySQL LEFT JOIN 3 tablesMySQL LEFT JOIN 3 个表
【发布时间】:2013-04-19 18:45:03
【问题描述】:

我有 3 张桌子:

人员(PersonID、姓名、SS)
恐惧(FearID,恐惧)
Person_Fear(ID、PersonID、FearID)

现在我想列出每个人都有任何与他们相关的恐惧(可以是多种恐惧,但也可以没有)。即使一个人没有与他们相关的恐惧,也必须显示 people 表。

我认为我需要进行 LEFT JOIN,但我的代码似乎不起作用:

SELECT persons.name, 
       persons.ss, 
       fears.fear 
FROM   persons 
       LEFT JOIN fears 
              ON person_fear.personid = person_fear.fearid 

我在这里做错了什么?

【问题讨论】:

  • 你试过我的解决方案了吗?

标签: mysql sql join


【解决方案1】:
SELECT p.*, f.Fear
FROM Persons p
LEFT JOIN Person_Fear pf ON pf.PersonID = p.PersonID
LEFT JOIN Fears f ON f.FearID = pf.FearID
ORDER BY p.PersonID

  1. 您需要从Persons 表中进行选择,以确保为每个人生成一行,无论他们是否有恐惧。
  2. 然后,您可以将加入 Person_Fear 留给每个人,如果他们没有任何条目(如您所愿),则为 NULL
  3. 最后,您在Person_Fear 上离开了加入Fears,以便您可以选择恐惧的名称。
  4. (可选)添加一个订单,以便将每个人的所有恐惧都列在一起,即使他们是在不同时间添加到 Person_Fear 表中的。

【讨论】:

    【解决方案2】:
    Select Persons.Name, Persons.SS, Fears.Fear
    From Persons
    LEFT JOIN Persons_Fear
    ON Persons.PersonID = Person_Fear.PersonID
    LEFT JOIN Fears
    ON Person_Fear.FearID = Fears.FearID;
    

    【讨论】:

    • 不鼓励使用纯代码的答案。请描述此代码在 OP 未实现的情况下做了什么。
    • 这是一个非常实用的答案。你们应该停止劝阻新手。如果你发现它太代码,你自己添加一些 cmets-y
    【解决方案3】:

    试试这个绝对有效。

    SELECT p.PersonID AS person_id,
       p.Name, p.SS, 
       f.FearID AS fear_id,
       f.Fear 
       FROM person_fear AS pf 
          LEFT JOIN persons AS p ON pf.PersonID = p.PersonID 
          LEFT JOIN fears AS f ON pf.PersonID = f.FearID 
       WHERE f.FearID = pf.FearID AND p.PersonID = pf.PersonID
    

    【讨论】:

    • 我无法让它工作,但我通过删除 AS 变量并仅使用完整的表名解决了这个问题
    • 任何人都可以评论左,左连接与左,内连接之间的性能差异
    【解决方案4】:

    您正试图将Person_Fear.PersonID 加入Person_Fear.FearID - 这真的没有意义。你可能想要这样的东西:

    SELECT Persons.Name, Persons.SS, Fears.Fear FROM Persons
    LEFT JOIN Person_Fear
        INNER JOIN Fears
        ON Person_Fear.FearID = Fears.FearID
    ON Person_Fear.PersonID = Persons.PersonID
    

    这通过中间表Person_FearPersons 连接到Fears。因为PersonsPerson_Fear 之间的连接是LEFT JOIN,所以您将获得所有Persons 记录。

    或者:

    SELECT Persons.Name, Persons.SS, Fears.Fear FROM Persons
    LEFT JOIN Person_Fear ON Person_Fear.PersonID = Persons.PersonID
    LEFT JOIN Fears ON Person_Fear.FearID = Fears.FearID
    

    【讨论】:

    • 我投了反对票,因为您的原始帖子没有引用所有 3 个表格。您已经纠正了这一点,但是您的 On 子句的嵌套错误。
    • +1 - 我知道,这看起来是迄今为止唯一正确的答案(至少在任何编辑之后)。
    • 顺便说一句,我不确定哪一个会更有效。我会打赌后者,因为如果没有PersonPerson_Fear 的关系,它就不需要将Person_Fear 的行加入Fears。谁能提供见解?
    • @AntP 在我看来,当您开始提出这样的问题时,您就是在钻研过早优化的范畴。把你的索引整理好,不要像那样担心细节。一个体面的查询优化器可能会为每个查询计划生成一个非常相似的查询计划。
    • @Aheho:实际上,没有。 @AntP 是正确的,这是一个很好的问题。许多优化器会产生不同的查询计划。一个原因是查询在逻辑上并不相同。 (好的,但前提是存在从Person_FearFear 的FK)。 MYSQL 的原始优化器可能不知道并使用该信息。
    【解决方案5】:
    Select 
        p.Name,
        p.SS,
        f.fear
    From
        Persons p
    left join
            Person_Fear pf
        inner join
            Fears f
        on
            pf.fearID = f.fearID
     on
        p.personID = pf.PersonID
    

    【讨论】:

      【解决方案6】:

      试试这个

          SELECT p.Name, p.SS, f.Fear 
          FROM Persons p 
          LEFT JOIN Person_Fear fp 
          ON p.PersonID = fp.PersonID
          LEFT JOIN Fear f
          ON f.FearID = fp.FearID
      

      【讨论】:

        猜你喜欢
        • 2016-12-16
        • 1970-01-01
        • 2013-02-20
        • 1970-01-01
        • 2021-11-06
        • 1970-01-01
        • 1970-01-01
        • 2013-05-14
        • 2019-08-12
        相关资源
        最近更新 更多