根据来自另一个表的匹配行查找表中的一组行

Posted

技术标签:

【中文标题】根据来自另一个表的匹配行查找表中的一组行【英文标题】:Finding set of rows in table based on matching rows from another table 【发布时间】:2021-12-04 23:48:45 【问题描述】:

我知道这个话题充其量是有点模​​糊,但找不到更好的方法来描述我的问题......

举个例子,我有以下两张表:

表A

IdA Code Value
123 A 1
123 B 2
123 C 3
456 A 4
456 F 6
456 E 7
...

表B

IdB Code Value
X A 1
X B 2
X C 3
Y G 2
Y D 8
Y C 3
Z A 1
Z B 2
Z C 3
Z D 5
...

TableA 中给定 IdA 的一组记录与 TableB 中具有特定 IdB 的等效记录集相关。

例如,对于 TableA 中的 IdA = 123,我正好有三行具有某些代码和值,这将“映射”到 TableB 中 IdB = X 的行,因为它具有相同的代码和值组合并且相同行数。请注意,它不会映射到 TableB 中的 IdB = Z,因为它有一个额外的代码 D 行,而 IdA = 123 在 TableA 中没有。

仅给定 IdA,如何最好地编写查询来查找 IdB?

如果知道代码和值,我可以做类似的事情:

SELECT b.IdB FROM TableB b
WHERE
    EXISTS(SELECT * FROM TableB x WHERE x.IdB = b.IdB AND x.Code = 'A' AND x.Value = '1') AND
    EXISTS(SELECT * FROM TableB x WHERE x.IdB = b.IdB AND x.Code = 'B' AND x.Value = '2') AND
    EXISTS(SELECT * FROM TableB x WHERE x.IdB = b.IdB AND x.Code = 'C' AND x.Value = '3') AND
    (SELECT COUNT(*) FROM TableB x WHERE x.IdB = b.IdB) = 3

但现在我只获得了 IdA 的值,因此我需要从 TableA 中查找值并将其组合到 TableB 的查询中。关于如何解决这个问题有什么聪明的想法吗?

【问题讨论】:

您的预期结果是什么? 【参考方案1】:

这是Relational Division Without Remainder的问题。

解决方法有很多,这里有一个:

带上TableB 并离开加入TableA 到它 但是计算来自 A 的整个值集的总和 按IdB分组 过滤,所以我们只有总计数等于匹配到 A 的数量的行(因为 COUNT(IdA) 只计算非空值)并且总计数也必须与我们的总行数相同想要匹配。
DECLARE @idA int = 123;

SELECT
  b.IdB
FROM TableB b
LEFT JOIN (
    SELECT *,
      total = COUNT(*) OVER ()
    FROM TableA a
    WHERE a.IdA = @idA
) a ON b.Code = a.Code AND b.Value = a.Value
GROUP BY
  b.IdB
HAVING COUNT(*) = COUNT(a.IdA)
  AND COUNT(*) = MIN(a.total);

db<>fiddle

【讨论】:

太棒了!并感谢您提供的信息链接!

以上是关于根据来自另一个表的匹配行查找表中的一组行的主要内容,如果未能解决你的问题,请参考以下文章

如何根据列中的一组行对数据框进行排名?

如何更新除该组中最新项目之外的一组行

根据另一个表中的列值选择一个表中的行?

根据列中的一组查找最大值行并在熊猫中进行透视

如何填充一列以区分 Impala 组中的一组行与其他行?

PostgreSQL删除数据