为找到所有匹配的父母的一般情况解决这个问题更有趣:) 请参阅底部的注释,了解如何将其用于更简单的情况(其中一个父键是固定的)。
我会给出我认为“合适”的解决方案,但我没有 Access(或 SQL Server)的副本可供查看它是否可以在其中工作。 (是的,我已经在这里针对数据库进行了测试......)
SELECT p1.column1, p2.column1
FROM parent p1 JOIN parent p2 ON p1.column1 < p2.column1
WHERE NOT EXISTS (SELECT 1
FROM (SELECT c1.column1, c1.column2 FROM child c1 WHERE c1.column1 = p1.column1) c1f
FULL OUTER JOIN
(SELECT c2.column1, c2.column2 FROM child c2 WHERE c2.column1 = p2.column1) c2f
ON c1f.column2 = c2f.column2
WHERE c1f.column1 IS NULL OR c2f.column1 IS NULL
);
所以希望你能看到我上面所说的内容是如何联系在一起的 :) 我会试着解释一下......
“外部”(第一个)选择生成 column1 值的组合(p1.column1 和 p2.column1)。对于每个组合,我们在“child”中列出这些值的行(这些是 c1f 和 c2f:c1f 表示“child 1 filtered”)并执行 FULL OUTER JOIN。根据我的经验,这是一个相对罕见的结构。我们想要匹配 所有 c1f 和 c2f 中的条目(使用它们的 column1 值),并找到任何 任一侧 没有对应条目的另一侧边。如果有任何这样的非匹配器,那么它们将显示为来自连接的行,其 column1 值为空。因此,父查询仅选择子查询中不存在此类行的 column1 值的组合,即 p1 的 column1 值的每个子行都有一个对应于 p2 的 column1 值的子行,反之亦然。
例如,对于 p1.column1 为“S1”且 p2.column2 为“S3”的迭代,该子查询(没有聚合)将产生:
c1f__column1 | c1f__column2 | c2f__column1 | c2f__column2
--------------+--------------+--------------+--------------
S1 | P1 | S3 | P1
S1 | P2 | |
并且正是第二行中的那些空值将该组合标记为不匹配。涉及到一些曲折的想法,当找到不匹配的组合更容易时,很容易专注于寻找匹配的组合。
作为最后的奖励,当我为此创建一些测试表时,我将 (column1,column2) 设置为 child 的主键,这恰好是驱动过滤表的完全外连接所需要的有效率的。赢! (所以请注意,我没有尝试处理 child 中的重复组合......但你可以在 c1f 和 c2f 派生中打“distinct”)
NB 基于 Matt 的评论,如果您的父值之一是已知的(即您只想列出与 S1 具有相同子项的所有父值),那么您只需拍打“and p1.column1 = 'S1'”最后。但是在这种情况下,将“parent p1 JOIN parent p2 ON p1.column1