【问题标题】:Multiple many-to-many relationships in SQLSQL中的多个多对多关系
【发布时间】:2018-03-21 02:38:28
【问题描述】:

如何查询同一结果集中的多个多对多关系?

我有两个表,我通常总是 LEFT JOIN 用于标准结果集:

tblPROJECTS-

id  |  jobnumber  |  jobname ...
--------------------------------------------------
1   |  1000       |  Project X
2   |  2000       |  Project Y
3   |  3000       |  Project Z

tblTASKS-

id  |  tasknumber |  jobnumber  |  taskname ...
--------------------------------------------------
1   |  10         |  1000       |  Project X: Task 1
2   |  20         |  1000       |  Project X: Task 2
3   |  30         |  2000       |  Project Y: Task 1

Tasknumber 是一个 GUID,独立于 jobnumber,但不会与多个作业相关。

我在 jobnumber 上 LEFT JOIN tblTASKS,因为并非所有项目都会有任务(目前)

但是我也有一个所有者表,它定义了 1-n 个用户,这些用户要么拥有整个工作,要么拥有单个任务(或两者兼有)。每个用户可以拥有多个工作和/或任务。 DB 的原始设计规定使用单个表。

tblOWNERS-

id  |  ownertype  |  ownerid  |  jobnumber  |  tasknumber ...
----------------------------------------------------------------
1   |  1          |  2        |  1000       |
2   |  1          |  4        |  1000       |
3   |  2          |  2        |             |  10

ownertype 为 1 表示用户拥有整个作业。 ownertype 为 2 表示用户拥有作业中的任务。

我正在尝试构建两个查询:

1) 与所有关联的工作所有者一起返回工作,并与所有关联的任务所有者加入该工作的所有任务。

jobnumber |  jobowners | tasknumber | taskowners ...
1000      |  2,4,...   | 10         | 2
2000      |            | 20         | 4,6,8...
3000      |  4,5,6...  | 30         | 

2) 给定所有者 ID,返回与其关联的所有作业和/或任务。

让我难倒的是来自/到同一张桌子的多个多对多。我能做到这一点吗?如果是这样,我是否正在寻找某种 UNION 或 INTERSECT (我要查找什么来学习)?或者,如果不是,那么对于这样的关系有什么更好的架构来支持它?

TIA!

【问题讨论】:

  • 您需要使用不同的别名两次加入 Owners 表。

标签: mysql sql many-to-many relational-database


【解决方案1】:

通常,您需要将外键放在 ERD 的多端,因此在这种情况下,您可能在表“tblPROJECTS”中有一个名为“ownerid”的字段,并且在 tblTASKS 中有“ownerid”。假设所有任务都有一个作业 ID 和一个所有者,并且所有项目也有一个所有者,您可以使用 INNER JOIN:

SELECT P.jobnumber,T.tasknumber,O1.id AS taskowner,O2.id AS jobowner
FROM tblTASKS T
INNER JOIN tblPROJECTS P ON P.jobnumber=T.jobnumber
INNER JOIN tblOWNERS O1 ON O1.id=T.ownerid
INNER JOIN tblOWNERS O2 ON O2.id=P.ownerid
WHERE O1.id=1

这不会像您描述的那样连接作业所有者和任务所有者,但会为每个返回一行,然后您可以在处理结果集时连接它们。

然后根据需要替换 WHERE 子句以获取给定作业编号的任务列表...

WHERE P.jobnumber=1000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 2018-02-17
    相关资源
    最近更新 更多