EzLo должен получить кредит за то, что привел меня к другому сообщению ( Как найти все связанные подграфы неориентированного графа ), которые позволили мне составить правильный ответ.
DECLARE @Graph TABLE (
A SmallInt NOT NULL,
B SmallInt NOT NULL
)
INSERT INTO @Graph (A, B)
VALUES
(11, 2), ( 2, 14), ( 2, 4), ( 5, 12),
( 6, 12), ( 12, 9), ( 8, 9), (10, 7),
( 1, 7), ( 7, 13), ( 7, 3);
WITH CTE_Idents AS (
SELECT A AS Ident FROM @Graph
UNION SELECT B AS Ident FROM @Graph
)
, CTE_Pairs AS (
SELECT A AS Ident1, B AS Ident2 FROM @Graph WHERE A <> B
UNION SELECT B AS Ident1, A AS Ident2 FROM @Graph WHERE A <> B
)
, CTE_Recursive AS (
SELECT
CTE_Idents.Ident AS AnchorIdent,
Ident1,
Ident2,
CAST(',' + CAST(Ident1 AS VARCHAR(2)) + ',' + CAST(Ident2 AS VARCHAR(2)) + ',' AS varchar(8000)) AS IdentPath
FROM
CTE_Pairs
INNER JOIN
CTE_Idents
ON CTE_Idents.Ident = CTE_Pairs.Ident1
UNION ALL
SELECT
CTE_Recursive.AnchorIdent,
CTE_Pairs.Ident1,
CTE_Pairs.Ident2,
CAST(CTE_Recursive.IdentPath + CAST(CTE_Pairs.Ident2 AS VARCHAR(2)) + ',' AS varchar(8000)) AS IdentPath
FROM
CTE_Pairs
INNER JOIN
CTE_Recursive
ON CTE_Recursive.Ident2 = CTE_Pairs.Ident1
WHERE
CTE_Recursive.IdentPath NOT LIKE CAST('%,' + CAST(CTE_Pairs.Ident2 AS VARCHAR(2)) + ',%' AS varchar(8000))
)
, CTE_RecursionResult AS (
SELECT AnchorIdent, Ident1, Ident2 FROM CTE_Recursive
)
, CTE_CleanResult AS (
SELECT AnchorIdent, Ident1 AS Ident FROM CTE_RecursionResult
UNION SELECT AnchorIdent, Ident2 AS Ident FROM CTE_RecursionResult
)
SELECT AnchorIdent, MAX(Ident) AS Ident FROM CTE_CleanResult GROUP BY AnchorIdent ORDER BY AnchorIdent