让我试着解释一下这个版本的查询:
select t1.field1 as t1field1, t2.field1 as t2field1
from (select t1.*,
count(*) over (partition by field1) as NumField2
from table1 t1
) t1 full outer join
(select t2.*,
count(*) over (partition by field1) as NumField2
from table2 t2
) t2
on t1.field2 = t2.field2
where t1.NumField2 = t2.NumField2
group by t1.Field1, t2.Field1
having count(t1.field2) = max(t1.NumField2) and
count(t2.field2) = max(t2.NumField2)
(在SQLFiddle上)。
这个想法是比较每对field1
值的以下计数。
- 每个值的数量
field2
。
field2
他们共享的值的数量。
所有这些都必须相等。
每个子查询计算field2
每个field1
值的值的数量。对于数据的第一行,这会产生:
1 A 2
1 B 2
2 A 3
2 D 3
2 E 3
. . .
对于第二张桌子
8 A 2
8 B 2
9 E 3
9 D 3
9 C 3
接下来,应用 ,要求计数和值full outer join
都匹配。field2
这会使数据相乘,产生如下行:
1 A 2 8 A 2
1 B 2 8 B 2
2 A 3 NULL NULL NULL
2 D 3 9 D 3
2 E 3 9 E 3
NULL NULL NULL 9 C 3
对于所有可能的组合,依此类推。请注意,NULL
出现 s 是由于full outer join
.
请注意,当您有匹配的一对(例如 1 和 8)时,没有包含NULL
值的行。当您有一对具有相同计数但它们不匹配时,那么您就有了NULL
值。当您有一对不同计数时,它们会被where
子句过滤掉。
过滤聚合步骤应用这些规则来获得满足第一个条件但不满足第二个条件的对。
having
本质上删除了任何具有NULL
值的对。当您count()
使用一列时,NULL
不包括值。在这种情况下,count()
列上的 小于预期值的数量 ( NumField2
)。