SQL查询探索具有多个父级的图

时间:2018-10-16 10:23:45

标签: sql sql-server oracle parent-child hierarchy

我需要探索一个描述图形的表,但是复杂性是由于每个节点可以具有不同类型的父级,因此,层次结构并非简单地跨越父级列和子级列< / p>

演示结构和数据

If object_id('dbo.TST_COMPONENT') is not null
DROP table TST_COMPONENT

CREATE TABLE TST_COMPONENT (
    [MAT_CODE] VARCHAR(max)
    , [SPEC_CODE] VARCHAR(max)
    , [COMP_MAT_CODE] VARCHAR(max)
    , [COMP_SPEC_CODE] VARCHAR(max)
    );

INSERT INTO TST_COMPONENT (
    [MAT_CODE], [SPEC_CODE], [COMP_MAT_CODE], [COMP_SPEC_CODE]
    )
VALUES
    ('M1', NULL, 'M2', NULL),
    ('M1', NULL, 'M4', NULL),
    ('M2', NULL, NULL, 'S3'),
    ('M2', NULL, 'M6', NULL),
    (NULL, 'S3', 'M5', NULL),
    ('M4', NULL, NULL, 'S4'),
    ('M5', NULL, NULL, NULL),
    ('M6', NULL, NULL, NULL),
    (NULL, 'S4', NULL, 'S5'),
    (NULL, 'S5', 'M7', NULL),
    ('M7', NULL, NULL, NULL);

在这种情况下,M1具有M2和M4作为子级,M2具有M6和S3,而S3具有M5。在另一个分支上,M4转到S4,然后到S6,最后到M7。

哪种方法是使用SQL查询探索这棵树的最快方法?更好的是,它适用于Oracle和SQL Server。

1 个答案:

答案 0 :(得分:1)

我正试图实现这样的目标

WITH MyCTE
AS ( SELECT MAT_CODE, SPEC_CODE, COMP_MAT_CODE, COMP_SPEC_CODE
FROM TST_COMPONENT
WHERE MAT_CODE = 'M1'
UNION ALL
SELECT C.MAT_CODE, C.SPEC_CODE, C.COMP_MAT_CODE, C.COMP_SPEC_CODE
FROM TST_COMPONENT C
    INNER JOIN MyCTE ON
    (
        ( C.MAT_CODE = MyCTE.COMP_MAT_CODE AND C.SPEC_CODE IS NULL)
        OR
        ( C.SPEC_CODE = MyCTE.COMP_SPEC_CODE AND C.MAT_CODE IS NULL)
    )
    --WHERE C.MAT_CODE = MyCTE.COMP_MAT_CODE AND C.SPEC_CODE = MyCTE.COMP_SPEC_CODE
)
SELECT * FROM MyCTE

这似乎满足了我的要求,只是我不确定这是否是最好的,是否真的涵盖了所有可能的情况。