【问题标题】:MySQL - How to use (LEFT) JOIN to join two tables via one table together?MySQL - 如何使用(LEFT)JOIN 通过一个表将两个表连接在一起?
【发布时间】:2015-09-10 10:08:59
【问题描述】:

一些背景和目标

我正在用 HTML/PHP 为我的网站上的一个人制作一个链接列表。它允许多项选择(使用属性“multiple”进行选择),它基本上看起来像这样:

╔══════════╗
║ Facebook ║
╠══════════╣
║ Google+  ║
╠══════════╣
║ Twitter  ║
╚══════════╝

所选项目将保存到 MySQL 数据库中,但这还不是全部。保存选择后,我想回去看看,选择了哪些选择。这意味着我必须使用我选择的选项在 PHP 中生成这个 select-元素。

数据库结构

最后编辑于 2015 年 6 月 24 日 13:23(芬兰时间)

MySQL 中,我有以下表格:

  1. 链接包括链接特定信息(链接地址、颜色等)
  2. 包括有关个人的信息(名字和姓氏、地址、电子邮件等)
  3. person_link 用作将表 linkperson 连接在一起的表(具有列 id_linkid_person em>)

表格如下(已尝试显示与此问题相关的列;数据是任意的,此处是为了演示):

链接

╔══════════╦════════════╗
║ id       ║ name       ║
╠══════════╬════════════╣
║ 1        ║ Facebook   ║
╠══════════╬════════════╣
║ 2        ║ Google+    ║
╠══════════╬════════════╣
║ 3        ║ Twitter    ║
╚══════════╩════════════╝

╔══════════╦═════════════╦═════════════╦══════════════╦═════════════════╗
║ id       ║ name_first  ║ name_last   ║ address      ║ email           ║
╠══════════╬═════════════╬═════════════╬══════════════╬═════════════════╣
║ 1        ║ Jack        ║ Johnson     ║ Wacko Street ║ NULL            ║
╠══════════╬═════════════╬═════════════╬══════════════╬═════════════════╣
║ 2        ║ Hanna       ║ Hill        ║ Hill Town    ║ hh@gmail.com    ║
╠══════════╬═════════════╬═════════════╬══════════════╬═════════════════╣
║ 3        ║ Eric        ║ Samson      ║ Wacko Street ║ NULL            ║
╚══════════╩═════════════╩═════════════╩══════════════╩═════════════════╝

person_link

╔═══════════╦═════════╦═════════════════════╗
║ id_person ║ id_link ║ address             ║
╠═══════════╬═════════╬═════════════════════╣
║ 2         ║ 1       ║ www.example.com     ║
╠═══════════╬═════════╬═════════════════════╣
║ 2         ║ 2       ║ www.hello.org       ║
╚═══════════╩═════════╩═════════════════════╝

问题

简而言之,我的问题是我无法在 MySQL 中组合适当的查询来实现预期目标。我见过很多关于两个表之间的 LEFT JOIN 的问题,但还没有遇到过将两个表连接在一起的附加表的问题。

我尝试了以下方法:

SELECT link.name, person.id
    FROM link
        LEFT JOIN person_link ON (link.id = person_link.id_link)
        JOIN person ON (person_link.id_person = person.id)
    WHERE person.id = 2

现在,我希望这种查询会在左侧列出所有链接,并在右侧并列特定人员的 ID(如果可用)。如果一个 id 匹配一个链接,那么这个链接是从 select 元素中选择的。这就是我想要的结果(NULL 表示缺少匹配):

╔══════════╦══════╗
║ Facebook ║  2   ║
╠══════════╬══════╣
║ Google+  ║  2   ║
╠══════════╬══════╣
║ Twitter  ║ NULL ║
╚══════════╩══════╝

为什么我想让表格看起来像这样?因为基于此表,我可以生成如下所示的选择元素:

╔═════════════════════╗
║ Facebook (SELECTED) ║
╠═════════════════════╣
║ Google+  (SELECTED) ║
╠═════════════════════╣
║ Twitter             ║
╚═════════════════════╝

但是,我没有查询成功,而是得到了这样的结果:

╔══════════╦══════╗
║ Facebook ║  2   ║
╠══════════╬══════╣
║ Google+  ║  2   ║
╚══════════╩══════╝

我的查询显然有问题,但我不知道是什么问题。所以,我的问题是,如何使用 (LEFT) JOIN 通过一个表将两个表连接在一起?

【问题讨论】:

    标签: php mysql join


    【解决方案1】:
    SELECT l.name, p.id
    FROM link l
    LEFT JOIN person_link pl 
        ON (l.id = pl.id_link)
    LEFT JOIN person p 
        ON (pl.id_person = p.id && l.id = pl.id_link && p.id = 2) 
    group by l.link
    

    或基于尼拉拉的回答

    SELECT l.name, pl.id_person
    FROM link l
    LEFT JOIN person_link pl 
        ON (l.id = pl.id_link && pl.id_person = 2)
    group by l.link
    

    【讨论】:

    • 好吧,这行得通。现在我想知道为什么。想学习,不只是彻头彻尾的复制粘贴。还在学习。 :D
    【解决方案2】:

    你需要允许人为NULL:

    SELECT link.name, person.id
    FROM link
    LEFT JOIN person_link ON (link.id = person_link.id_link)
    LEFT JOIN person ON (person_link.id_person = person.id)
    WHERE (person.id = 2 OR person.id IS NULL)
    

    你也可以这样写:

    SELECT link.name, person.id
    FROM link
    LEFT JOIN person_link ON (link.id = person_link.id_link)
    LEFT JOIN person ON (person_link.id_person = person.id AND person.id = 2)
    

    【讨论】:

      【解决方案3】:

      我建议你

      SELECT link.name, person_link.id_person FROM link LEFT JOIN person_link 
      ON link.id = person_link.id_link WHERE person_link.id_person = 2
      

      【讨论】:

      • 嗯,它似乎输出了我已经在我的问题中发布的错误结果。我想知道 person_link-table 中由 id_link 和 id_person 组成的主键是否可能是一个问题?另外,您能否解释一下为什么这应该起作用而不是我提供的查询?
      • 这是更优化的查询。如果您在两个表中获得所需的结果,那么为什么要查询 3 个表。
      • 我使用 3 个表的原因是因为每个人可以拥有的链接数量可以变化。将每个链接类型设置为人员表中自己的列是没有意义的。相反,我会使用 person_link-table 将一个人连接到他的链接列表。这有意义吗?如果没有,您会推荐更好的方法吗? :0
      • 你没有在你的问题中提到这些旧东西。我刚刚优化了您的查询,您可以根据需要修改我的查询。
      • 你向我们展示了所有三个表的表结构和所需的结果集,我会给你准确的查询。好吗?
      【解决方案4】:

      一些示例数据会很好(http://sqlfiddle.com/ 会很完美),但从我的角度来看,这个未经测试的查询应该可以完成这项工作。

      SELECT person.*, link.* 
      FROM person_link 
      RIGHT JOIN link ON id_link = link.id 
      INNER JOIN person ON id_person = person.id
      WHERE id_person = 2
      

      【讨论】:

      • 嗯,感谢您提到 SQLFiddle。提问时似乎是一个方便的工具。 :)
      猜你喜欢
      • 2016-09-15
      • 2016-03-15
      • 2016-07-21
      • 1970-01-01
      • 2012-06-21
      • 2020-01-18
      • 1970-01-01
      • 1970-01-01
      • 2012-03-15
      相关资源
      最近更新 更多