-- 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 ax=bx and ay=by 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
The above method allows you to get groups specified with their peers in a very optimal way. It works well with large databases, decomposing groups into the number of members and takes a minimum and a maximum. Groups are quickly reduced using direct joins, and for the remaining matches only, the full table refers to joining back with the identifiers of groups A and B to determine if they are equivalent groups.
If you had three identical groups (101,103,104), they will be displayed as three separate lines (101,103), (101,104), (103,104) - since each pair forms a peering, so this query is best used if you already know one of the groups for which you want to find peers. This filter would fit in the first subquery.