首页 > 解决方案 > SQL 查询探索具有多个父级的图

问题描述

我需要探索一个描述图表的表,但复杂性是由于每个节点都可以有不同类型的父节点,因此层次结构不是简单地跨父列和子列完成

演示结构和数据

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。

标签: sqlsql-serveroracleparent-childhierarchy

解决方案


我试图实现这样的目标

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

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


推荐阅读