Использование чистого SQL.
Основная идея состоит в том, что два набора A и B, равные, определяются тем, что A является подмножеством B, а B является подмножеством A.
И мыможно проверить, является ли B подмножеством A, получив члены B, которые находятся в A, посчитав их и проверив, равно ли это счету в A.
Поскольку это довольно сложный шаг, я просто сделал этопутем перекрестного применения подзапроса, отфильтрованного к командам A и B. Может быть более элегантный способ.
WITH MembersAll AS
(
SELECT Team_Id, Member_Id FROM Members
UNION
-- Consider leaders as members.
SELECT Team_Id, Leader_Id AS Member_Id FROM Teams
),
-- Teams and any teams which are a subset of that team:
TeamSubsetTeam AS (
SELECT
ThisTeam.Team_Id,
OtherTeam.Team_Id AS SubsetTeam_Id
FROM Teams AS ThisTeam
CROSS JOIN Teams AS OtherTeam -- Considering all pairs of teams.
CROSS APPLY (
-- Get the members in both teams,
-- left join so that we have all members from a given team
-- and all of the members in the other team that are in the given team
-- then filter on the counts of these being the same.
SELECT
COUNT(MembersThisTeam.Member_Id) AS MemberCountThisTeam,
COUNT(MembersOtherTeamInThisTeam.Member_Id) AS MemberCountOtherTeamInThisTeam
FROM MembersAll AS MembersThisTeam
LEFT JOIN MembersAll AS MembersOtherTeamInThisTeam
ON MembersThisTeam.Member_Id = MembersOtherTeamInThisTeam.Member_Id
AND MembersOtherTeamInThisTeam.Team_Id = OtherTeam.Team_Id
WHERE MembersThisTeam.Team_Id = ThisTeam.Team_Id
) MemberCounts
WHERE MemberCounts.MemberCountThisTeam = MemberCounts.MemberCountOtherTeamInThisTeam
),
-- Teams and any teams which are equivalent to that team (including itself):
TeamEquivalentTeam AS (
-- From set theory, team A is equivalent to team B if
-- team A is a subset of team B and
-- team B is a subset of team A.
SELECT
Team_Id,
SubsetTeam_Id AS EquivalentTeamId
FROM TeamSubsetTeam
WHERE Team_Id IN (
SELECT SubsetTeam_Id FROM TeamSubsetTeam AS SubsetTeamSubsetTeam
WHERE SubsetTeamSubsetTeam.Team_Id = TeamSubsetTeam.SubsetTeam_Id
)
)
-- The specified post-processing step.
-- Doesn't seem particularly useful but you can do whatever you like
-- now you have the information in TeamEquivalentTeam.
SELECT DISTINCT MIN(EquivalentTeamId) AS FirstEquivalentTeam
FROM TeamEquivalentTeam
GROUP BY Team_Id
Возвращает:
FirstEquivalentTeam
1
2
4