"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Consejos para encontrar todos los subgrafos conectados en gráficos no dirigidos utilizando CTE recursivo

Consejos para encontrar todos los subgrafos conectados en gráficos no dirigidos utilizando CTE recursivo

Publicado el 2025-04-14
Navegar:605

How to Find All Connected Subgraphs in an Undirected Graph Using a Recursive CTE?

cómo encontrar todos los subgrafías conectados de un gráfico no dirigido

Problema:

dada una tabla con dos columnas que contienen identificadores, encuentran todos los grupos de identificadores que están conectados a cada uno Otro.

Ejemplo Tabla:

[&] 3 g 4 c h 5 [&]] 6 d 7 8 [&] [&] [&] h gr.members
id identificador1 identificer2
&] 1 a c
2 b f
[]
f
e k
9 l
Deseed Salida:
identificador gr_id
[&] &&]

c 1 (a, c, g, h, l) 2 (b, d, f, j) (e, k) f 1 (a, c, g, h, l) h j [&] &&] 3 l 1 (a, c, g, h, l) (i) [&] Solución: el La siguiente consulta utiliza una sola consulta recursiva para encontrar todas las subgrafías conectadas: muestra Salida: identificador gr_id gr.members a 1 (A, C, C, G, H, L) c
d
e 3
[&] 2 (b, d, f, j)
g
1 (a, c, g, h, l)
2 (b, d, f, j) k
(e, k) [&]
[y] &&] i 4
con Cte_idents COMO ( Seleccione Ident1 como ident De @T UNIÓN Seleccione Ident2 como ident De @T ) , Cte_pairs COMO ( Seleccione Ident1, Ident2 De @T Donde ident1 & lt; & gt; Ident2 UNIÓN Seleccione Ident2 como Ident1, Ident1 como Ident2 De @T Donde ident1 & lt; & gt; Ident2 ) , Cte_recursive COMO ( SELECCIONAR Cast (cte_idents.ident como varchar (8000)) como anclaje , Ident1 , Ident2 , Cast (',' ident1 ',' ident2 ',' como varchar (8000)) como identpath , 1 como lvl DE Cte_pairs Inner Join CTE_IDENTS en cte_idents.ident = cte_pairs.ident1 Unión todos SELECCIONAR Cte_recursive.anchorident , Cte_pairs.ident1 , Cte_pairs.ident2 , Cast (CTE_recursive.identPath CTE_Pairs.ident2 ',' como Varchar (8000)) como IdentPath , Cte_recursive.lvl 1 como lvl DE Cte_pairs Inner Join cte_recursive en cte_recursive.ident2 = cte_pairs.ident1 DÓNDE Cte_recursive.identpath no como el cast ('%,' cte_pairs.ident2 ',%' como Varchar (8000)) ) , Cte_recursionResult COMO ( Seleccione AnchorRident, Ident1, Ident2 De cte_recursive ) , Cte_cleanResult COMO ( Seleccione AnchorRident, ident1 como identificación De cte_recursionResult UNIÓN Seleccione AnchorRident, Ident2 como identificación De cte_recursionResult ) SELECCIONAR Cte_idents.ident , Caso cuando ca_data.xml_value es nulo Entonces cte_idents.ident else CA_DATA.XML_VALUE END ASMERMBERS , Dense_rank () over (ordenar por Caso cuando ca_data.xml_value es nulo Entonces cte_idents.ident else CA_DATA.XML_VALUE END ) Como groupid DE Cte_idents Aplicar cruzado ( Seleccione CTE_CleAnresult.ident ',' De cte_cleanResult Donde cte_cleanResult.anchorident = cte_idents.ident Pedido de cte_cleanResult.ident para ruta xml (''), tipo ) Como ca_xml (xml_value) Aplicar cruzado ( Seleccione CA_XML.XML_VALUE.VALUE ('.', 'Nvarchar (max)') ) Como ca_data (xml_value) DÓNDE Cte_idents.ident no es nulo Orden por identificación;
b 2 (B, D, F, J)

1 (a, c, g, h, h, l)

WITH
CTE_Idents
AS
(
    SELECT Ident1 AS Ident
    FROM @T

    UNION

    SELECT Ident2 AS Ident
    FROM @T
)
,CTE_Pairs
AS
(
    SELECT Ident1, Ident2
    FROM @T
    WHERE Ident1 <> Ident2

    UNION

    SELECT Ident2 AS Ident1, Ident1 AS Ident2
    FROM @T
    WHERE Ident1 <> Ident2
)
,CTE_Recursive
AS
(
    SELECT
        CAST(CTE_Idents.Ident AS varchar(8000)) AS AnchorIdent 
        , Ident1
        , Ident2
        , CAST(','   Ident1   ','   Ident2   ',' AS varchar(8000)) AS IdentPath
        , 1 AS Lvl
    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   CTE_Pairs.Ident2   ',' AS varchar(8000)) AS IdentPath
        , CTE_Recursive.Lvl   1 AS Lvl
    FROM
        CTE_Pairs
        INNER JOIN CTE_Recursive ON CTE_Recursive.Ident2 = CTE_Pairs.Ident1
    WHERE
        CTE_Recursive.IdentPath NOT LIKE CAST('%,'   CTE_Pairs.Ident2   ',%' 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
    CTE_Idents.Ident
    ,CASE WHEN CA_Data.XML_Value IS NULL 
    THEN CTE_Idents.Ident ELSE CA_Data.XML_Value END AS GroupMembers
    ,DENSE_RANK() OVER(ORDER BY 
        CASE WHEN CA_Data.XML_Value IS NULL 
        THEN CTE_Idents.Ident ELSE CA_Data.XML_Value END
    ) AS GroupID
FROM
    CTE_Idents
    CROSS APPLY
    (
        SELECT CTE_CleanResult.Ident ','
        FROM CTE_CleanResult
        WHERE CTE_CleanResult.AnchorIdent = CTE_Idents.Ident
        ORDER BY CTE_CleanResult.Ident FOR XML PATH(''), TYPE
    ) AS CA_XML(XML_Value)
    CROSS APPLY
    (
        SELECT CA_XML.XML_Value.value('.', 'NVARCHAR(MAX)')
    ) AS CA_Data(XML_Value)
WHERE
    CTE_Idents.Ident IS NOT NULL
ORDER BY Ident;

e 3

(e, k) (a, c, g, h, h, l) i 4 (i) j 2 [&] [&] [&] &&] k 3 (e, k) 5 la tabla CTE_CleanResult extrae los identificadores conectados para cada identificador de ancla La ruta XML y la cruz se aplican para concatenar los identificadores conectados para cada grupo. dense_rank () se usa para asignar ID de grupo únicas a cada grupo.
syle s, ando] &&] g 1
h 1 (a, c, g, h, l) &&]
(b, d, j)
&] z
(z) La tabla CTE_idents contiene todos los identificadores únicos en el gráfico.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3