计算总树结构

1 sql-server

我有一个包含 object_id、object_name、derived_from_object_id 的表

我需要查看哪些函数才能根据提供的 object_id 提供派生总数?

例子

1    object1    0  
2    object2    1  
3    object3    1  
4    object4    0  
5    object5    3  
6    object6    2  
7    object7    3  
8    object8    5  
Run Code Online (Sandbox Code Playgroud)

没有定义从对象或子对象派生的最大数量。因此,如果我想要 objectid 1 的总数,结果将为 7。

我想过编写一个存储过程,它只是为每个对象 id 返回一个计数,然后它会为每个有子对象的 id 调用自己。虽然我认为这会奏效,但我认为这完全是错误的方向。

Pau*_*ite 5

您可以使用递归公用表表达式从特定起点查找所有派生。

表格和数据

DROP TABLE IF EXISTS dbo.ObjectTree;

CREATE TABLE dbo.ObjectTree
(
    [object_id] integer NOT NULL
        CONSTRAINT [PK dbo.ObjectTree object_id]
        PRIMARY KEY CLUSTERED,
    [object_name] varchar(50) NOT NULL
        CONSTRAINT [UQ dbo.ObjectTree object_name]
        UNIQUE NONCLUSTERED,
    derived_from_object_id integer NULL
        CONSTRAINT [FK object_id]
        FOREIGN KEY (derived_from_object_id)
        REFERENCES dbo.ObjectTree ([object_id]),

    INDEX [IX dbo.ObjectTree derived_from_object_id] (derived_from_object_id)
);

INSERT dbo.ObjectTree
    ([object_id], [object_name], derived_from_object_id)
VALUES
    (1, 'object1', NULL),  
    (2, 'object2', 1),  
    (3, 'object3', 1),  
    (4, 'object4', NULL),  
    (5, 'object5', 3),  
    (6, 'object6', 2),  
    (7, 'object7', 3),  
    (8, 'object8', 5);
Run Code Online (Sandbox Code Playgroud)

递归查询

-- Where to start
DECLARE @ObjectID integer = 1;

WITH R AS
(
    -- Anchor
    SELECT
        OT.[object_id]
    FROM dbo.ObjectTree AS OT
    WHERE
        OT.[object_id] = @ObjectID

    UNION ALL

    -- Recursive
    SELECT
        OT.[object_id]
    FROM R
    JOIN dbo.ObjectTree AS OT
        ON OT.derived_from_object_id = R.[object_id]
) 
SELECT
    derivations = COUNT_BIG(*)
FROM R
OPTION MAXRECURSION(0);
Run Code Online (Sandbox Code Playgroud)

这为 返回 7 [object_id] = 1

试试看 dbfiddle 图标数据库<>小提琴.

使用 MAXRECURSION

MAXRECURSION 查询提示可用于防止形成不良的递归CTE从进入无限循环。如果这对您来说是一个问题,请使用合适的最大递归级别而不是上面的零(无限制)。默认(无提示)为 100。