假设我们有表 A 和表 B。从技术上讲,这是一个多对多的关系。A 中的一个条目可以与 B 中的多个条目相关联,反之亦然。当我有一个返回一组 B 条目的子查询时,就会出现我的问题。这些与 A 匹配,但我还想获取 B 中与 A 关联的所有条目,这可能是子查询的超集。因此,我必须将 A 连接回 B。需要注意的是,我需要返回来自 A 和 B 的信息,这排除了许多可能的技术。
我想做的是从 A 开始,加入 B,然后用子查询过滤,如果 B 中的条目在子查询中匹配,那么 B 中与 A 中的条目相关联的所有条目将被退回。
例如,假设条目 A1 与 B1、B2 和 B3 相关联。如果我们的子查询包含 B1 并且我们从 B 连接到 A,那么我们将获得包含 A1 和 B1 的一行。如果我们重新加入 B,我们可以得到 A1 和 B1、B2 和 B3 三行。我想做的是找到一个可以将 A 连接到 B 的函数、表达式等,然后看到 B1 在子查询中并且 B1 与 A1 关联,因此返回 A1 的所有行,我们得到 B1, B2 和 B3 三排。如果 A2 与 B4 和 B5 相关联并且它们都不包含在子查询中,则应从结果中排除 A2。基本上,关联中的一次命中会返回关联的所有行。通过这种方式,我们可以将其视为从 A 到 B 的一对多关系。
绘制它:
A | B
----------
A1 | B1
A1 | B2
A1 | B3
A2 | B4
A2 | B5
其中 A1 和 B1、B2 和 B3 都是键(实际上是随机生成的两列 bigint,但这有点简化了事情),它们作为外键出现在另一个表中。在第一个示例中:
WITH SUB (ID) AS (Subquery)
SELECT bb.*, aa.*
FROM SUB
JOIN B bb
ON bb.OTHER_ID = SUB.ID
JOIN A aa
ON bb.ID = aa.ID
其中,当子查询返回 B1 时,将为我们提供:
A | B
----------
A1 | B1
现在,如果我们将其附加到查询并将 SELECT 更改为 aa。, bb2。:
JOIN B bb2
ON aa.ID = bb2.ID
然后我们得到 A1 的所有行,如第一个示例表所示。但是,这需要重新加入 B,我想避免这种情况。另请注意,子查询不返回 B.ID,而是返回一个单独的标识符 B.OTHER_ID。相反,考虑一下:
SELECT aa.*, bb.*
FROM A aa
JOIN B bb
ON aa.ID = bb.ID
WHERE
--Insert function here that will take the subquery, and if any row in B
--is present in the set returned by the subquery, then ALL rows in A that include
--at least one matching row will be returned with all related rows in B
这是对我实际尝试做的事情的简化,但原因是我将 B 加入 A,然后再加入 A 到 B 太昂贵了(由于规范化,中间有几张表)。有没有办法通过仅将 A 加入 B 来做到这一点,还是我希望一些不存在的东西?我不打算重写查询以增强可读性。我只是在寻找一种逻辑处理关系以减少必要连接数量的方法。
很抱歉不止一次地问这个问题,但我认为我无法正确传达我正在尝试做的事情。也许这是不可能的。