-- sample table for discussion
CREATE TABLE tbl
(id int, groupid varchar(2), memberid varchar(2));
INSERT INTO tbl
(id, groupid, memberid)
VALUES
(6, 'g4', 'm1'),
(7, 'g4', 'm2'),
(8, 'g6', 'm1'),
(9, 'g6', 'm3'),
(1, 'g1', 'm1'),
(2, 'g1', 'm2'),
(3, 'g2', 'm1'),
(4, 'g2', 'm2'),
(5, 'g2', 'm3')
;
-- the query
select a.groupid, b.groupid peer
from (select groupid, count(*) member_count, min(memberid) x, max(memberid) y
from tbl
group by groupid) A
join
(select groupid, count(*) member_count, min(memberid) x, max(memberid) y
from tbl
group by groupid) B
on a.groupid<b.groupid and a.member_count=b.member_count and a.x=b.x and a.y=b.y
join tbl A1
on A1.groupid = A.groupid
join tbl B1
on B1.groupid = B.groupid and A1.memberid = B1.memberid
group by A.groupid, b.groupid, A.member_count
having count(1) = A.member_count;
-- the result
GROUPID PEER
g1 g4
上面显示了一种以groups
高度优化的方式与同行一起列出的方法。通过将组分解为成员计数并采用最小值和最大值,它适用于大型数据库。使用直接连接可以快速减少组,并且仅对于剩余的匹配项,查询完整的表并重新加入组 id A 和 B 以确定它们是否是等效组。
如果您有 3 个相似的组 (101,103,104),这些组将显示为三个单独的行 (101,103),(101,104),(103,104) - 因为每一对都形成一个对等互连,因此如果您已经知道其中一个,最好使用这样的查询您要为其查找对等的组。此过滤器将适合第一个子查询。