从两个表中获取行,另一个表中有多个匹配项

Get rows from two tables with multiple matches in the other

我有两个所有相似字段的表:

table_1: 
field_1, field_2, field_3, field_4
 

table_2: 
field_1, field_2, field_3, field_4

这里field_1可以作为外键连接两张表

我想从 table_1table_2 中获取在 table_1 中至少有一行但在 table_2 中有不止一行的所有行,反之亦然相反。

到目前为止,我已经尝试了这些相关的解决方案:

从 table_1 中获取在 table_2 中有多个匹配记录的所有记录的一种方法是计算子查询中匹配记录的数量,并在其上设置条件:

SELECT * 
FROM table_1 t1 
WHERE (SELECT count(*) 
       FROM table_2 t2 
       WHERE t1.field_1 = t2.field_1) > 1

如果您希望在一个查询中包含这两个方面,您可以将它们与 UNION 组合:

SELECT * 
FROM table_1 t1 
WHERE (SELECT count(*) 
       FROM table_2 t2 
       WHERE t1.field_1 = t2.field_1) > 1
UNION
SELECT * 
FROM table_2 t2 
WHERE (SELECT count(*) 
       FROM table_1 t1 
       WHERE t1.field_1 = t2.field_1) > 1

假设两个 table 具有相同的行类型:所有相同的列名和类型(至少兼容),您可以使用 row types 来简化:

SELECT (t).*
FROM  (SELECT t, count(*) AS ct1 FROM table_1 t GROUP BY 1) t1
JOIN  (SELECT t, count(*) AS ct2 FROM table_2 t GROUP BY 1) t2 USING (t)
WHERE t1.ct1 > 1
   OR t2.ct2 > 1;
  1. 分组重复并记住每个 table 中的计数。
  2. 加入两个 tables,这会删除其他 table.
  3. 中所有不匹配的行
  4. 过滤至少一侧有多个副本的行。
  5. 在外部 SELECT decompose the row type 照常获取列。

我没有 return 行数。如果您需要这些,请在外部 SELECT.

中添加 ct1ct2

这要求每个列类型都支持相等运算符 =
一个突出的例子是 json。 (但是 jsonb 确实如此。)参见:

  • How to query a json column for empty objects?

如果您有这样的列,请转换为 text 来解决它。或者您可以使用散列值 - 这也有助于非常宽的行 and/or 许多重复项的性能。相关: