Jeg skrev et svar på et lignende spørgsmål for et stykke tid siden:Sådan finder du alle forbundne undergrafer i en urettet graf . I det spørgsmål brugte jeg SQL Server. Se det svar for en detaljeret forklaring af mellemliggende CTE'er. Jeg tilpassede den forespørgsel til Postgres.
Det kan skrives mere effektivt ved hjælp af Postgres array-funktionen i stedet for at sammenkæde stien til en tekst
kolonne.
WITH RECURSIVECTE_IdentsAS( SELECT old AS Ident FROM identiteter UNION SELECT new AS Ident FROM identiteter),CTE_PairsAS( SELECT old AS Ident1, new AS Ident2 FROM identiteter WHERE old <> new UNION SELECT new AS Ident1, old AS Ident2 FROM identiteter WHERE old <> new),CTE_RecursiveAS( SELECT CTE_Idents.Ident AS AnchorIdent , Ident1 , Ident2 , ',' || Ident1 || ',' || Ident2 || ',' AS IdentPath , 1 AS Lvl FROM CTE_Pairs INNER JOIN CTE_Idents ON CTE_Idents.Ident =CTE_Pairs.Ident1 UNION ALLE VÆLG CTE_Recursive.AnchorIdent , CTE_Pairs.Ident1 , CTE_Pairs.Ident2 , CTE_Recursive.CTE_Pairsive.CTE_Pair AS1 | CTE_Recursive.CTE_Pair AS1 | INNER JOIN CTE_Recursive PÅ CTE_Recursive.Ident2 =CTE_Pairs.Ident1 HVOR CTE_Recursive.IdentPath IKKE LIKE ('%,' || CTE_Pairs.Ident2 || ',%')),CTE_Recursi onResultAS( SELECT AnchorIdent, Ident1, Ident2 FROM CTE_Recursive),CTE_CleanResultAS( SELECT AnchorIdent, Ident1 AS Ident FROM CTE_RecursionResult UNION SELECT AnchorIdent, Ident2 AS Ident FROM CTE_RecursionResult),CTE_GroupsASdentTE.CTE_RecursionResults(CTE_GroupsASdentTE. Ident) ORDER BY COALESCE(CTE_CleanResult.Ident, CTE_Idents.Ident)) AS AllIdents FROM CTE_Idents LEFT JOIN CTE_CleanResult ON CTE_CleanResult.AnchorIdent =CTE_Idents.Idents.Idents.Ident GROUP) BY CTE_IdentsUPs;
Jeg tilføjede en række (7,X,Y)
til dine prøvedata.
Resultat
| allidents ||------------------------|| Lydia,Mary,Nancy || Albert,Bob,Charles || X,Y || Zoe |