如何在单个查询中组合 2 个或多个桥接表

Posted

技术标签:

【中文标题】如何在单个查询中组合 2 个或多个桥接表【英文标题】:how to combine 2 or more bridge tables in a single query 【发布时间】:2009-12-19 16:11:31 【问题描述】:

我有以下表格:

表格:人员(id、first、last、age、phone 等) 表:角色(ID、名称) 表:技能(ID、姓名) 表:People_Roles(id、personID^、roleID^) 表:People_Skills(id、personID^、skillID^)

^ = foreign key

我基本上想要一个查询,它可以为我提供所有人员及其角色和技能的完整结果集。

Person.First、Person.Last、Roles.Name、Skills.Name

【问题讨论】:

这看起来像家庭作业 不幸的是没有。 .现在我基本上正在运行许多查询(每行一个)并且需要很长时间,所以我试图将所有查询合并到一个查询中。 . @monksy 谁在乎它是否是家庭作业?问题就是问题! 【参考方案1】:
SELECT p.first, p.last, r.name, s.name
FROM People p
LEFT JOIN People_Roles pr
ON pr.personID = p.id
INNER JOIN Roles r
ON pr.roleID = r.id
LEFT JOIN People_Skills ps
ON ps.personID = p.id
INNER JOIN Skills s
ON ps.skillID = s.id

此查询将选择您所有的人,即使是没有分配RolesSkills 的人。

【讨论】:

但是如果我做所有的内部连接,如果有一个有技能的人而不是一个角色,那么它不会显示记录。我想查看所有组合。我以为这是一个外部连接?? @oo 我已经写了关于它的评论:)。更新了您的答案。 这仍然只给我有技能或角色的行。 .如果有一个没有技能或行的人怎么办。 .这将如何显示? @oo 该人将显示为技能和角色名称均为 NULL 的人。一旦我们使用 LEFT JOIN,它就会返回左表中的所有记录,即 People 表。【参考方案2】:

此查询将起作用:

SELECT Person.First, Person.Last, Roles.Name, Skills.Name  
FROM People 
    LEFT JOIN People_Skills 
        ON People.id = People_Skills.personID
    INNER JOIN Skills
        ON People_Skills.skillID = Skills.id
    LEFT JOIN People_Roles 
        ON People.id = People_Roles.personID
    INNER JOIN Roles
        ON People_Roles.roleID = Skills.id

顺便说一下,为什么您的“桥”表有自己的 ID。我只会使用由 PersonID 和相应的外键(skillsID 或rolesID)组成的compound key 来确保每一对只能生成一次。

【讨论】:

但是如果我做所有的内部连接,如果有一个有技能的人而不是一个角色,那么它不会显示记录。我想查看所有组合。我以为这是一个外部连接?? 同意,但我想我需要在代码中处理这个问题。 .或者回到我原来的方法,即对 people 表中的每条记录的每个桥表进行单独查询。 . 执行 where 子句并比较“is Null”以删除您不想要的空行。 而左连接可能比完全连接更好 更新了查询以返回完整的结果集,如上所述。

以上是关于如何在单个查询中组合 2 个或多个桥接表的主要内容,如果未能解决你的问题,请参考以下文章

MySQL ----- 组合查询 UNION(十五)

MySQL ----- 组合查询 UNION(十五)

如何在同一个表上组合两个查询以在 MySQL 中获得单个结果集

在LINQ中组合多个表

第十七章 组合查询

如何在单个过程中编写多个选择查询?