从 reference/join-table 获取所有 Many:Many 关系

Get all Many:Many relationships from reference/join-table

我在 Many:Many 场景中查询可能的关系时遇到困难。

我展示我的模式:

做的知道如何用这个模式查询是:

尝试要做的是:

我的第一个问题是:

回顾一下:

术语

您的术语似乎是正确的 - "many to many",通常写成带冒号的 "many:many"。有时中间的table(band_members)被称为"bridge table".

您可能会删除 band_members.id,因为这两个外键也构成了一个复合主键(而且主键实际上可以这样定义,因为通常 User 不能是同一个的成员Band 两次。唯一的例外是用户可以在同一 Band 中担任多个角色)。

解决方案

从表面上看,这听起来很简单——我们可以看到 table 之间的关系,通常只需在它们之间使用一个 INNER JOIN。共有三个 table,因此这将是两个联接。

但是,我们必须首先正确地概念化问题。我们遇到的问题是用户和乐队成员(用户 ID)之间的连接实际上用于两件事:

  • 哪个用户属于哪个频段
  • 按用户过滤

所以要做到这一点,我们需要引入一个具有多种用途的 table:

SELECT
    Users.first_name, Users.last_name
FROM Users
INNER JOIN Band_Members Band_Members1 ON (Band_Members1.user_id = Users.Id)
INNER JOIN Band_Members Band_Members2 ON (Band_Members1.band_id = Band_Members2.band_id)
WHERE
    Band_Members2.user_id = 1

你可以在这里看到我加入了两次Band_Members,当一次这样做时,必须给它们起不同的别名,这样它们就可以被单独引用了。第一个实例在用户 table 和网桥 table 之间进行了明显的连接,第二个实例在 "Users who are in Bands" 和 "Bands that I am in" 之间进行了 link。

当然,此解决方案要求您知道自己的用户 ID。如果您想执行类似的查询但根据您的姓名进行过滤,那么您将必须加入用户 table 的另一个(重新别名)副本,以便您可以区分这两个不同的目的: "Users who are in bands" 和 "your User".