«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Как мы группируем связанные идентификаторы в неориентированном графе, представленном двумя столбцами, «Идентификатор1» и «Идентификатор2», и присваиваем им уникальные идентификаторы группы?

Как мы группируем связанные идентификаторы в неориентированном графе, представленном двумя столбцами, «Идентификатор1» и «Идентификатор2», и присваиваем им уникальные идентификаторы группы?

Опубликовано 31 октября 2024 г.
Просматривать:625

How do we group related identifiers in an undirected graph represented by two columns, \'Identifier1\' and \'Identifier2\', and assign them unique group IDs?

Нахождение связанных подграфов в неориентированном графе

Задача:

Данный неориентированный граф представлен двумя столбцами: «Идентификатор1» и «Идентификатор2», как группировать связанные друг с другом идентификаторы и присваивать им уникальные групповые идентификаторы?

Решение:

Эту проблему можно решить, рассматривая данные как ребра в графе и проходя все ребра рекурсивно.

Рекурсивный алгоритм:

  1. Создайте таблицу, содержащую все уникальные идентификаторы из обоих столбцов.
  2. Создайте таблицу, содержащую все ребра (пары идентификаторов) в обоих столбцах. направления.
  3. Определите рекурсивный запрос, который обходит граф, начиная с каждого идентификатора, и строит путь пройденных идентификаторов.
  4. Группируйте результаты по начальному идентификатору (идентификатору привязки), чтобы идентифицировать связанные компоненты.
  5. Назначьте уникальный идентификатор группы каждому подключенному компоненту на основе идентификатора привязки.

Пример запроса (SQL):

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;

Ключевые моменты:

  • Рекурсивное CTE (Common Table Expression) обходит граф и создает связанные компоненты.
  • Последний оператор SELECT назначает группу идентификаторы и генерирует выходные данные в нужном формате.
  • Это решение оптимизировано, чтобы избежать избыточных вычислений и обеспечить эффективные результаты.
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3