通过 CTE 创建任务表

问题描述 投票:0回答:1

在 SQL Server 中,我有一个名为任务的表,其中包含列:

任务id 任务名称 任务权重 任务父级
1, t1
2 t2 1
3 t3 0.03 1
4 t4 0.04 2
5 t5 0.03 2
6 t6
7 t7 0.01 6

task_parent
列是一个外键,可能为空或与此表中的另一个
task_id
相关。

我想编写一个 CTE 来在像 MS Project 这样的工作表中显示任务,其中具有一些递归子级的任务行的 task_weight 是从其子级中总结出来的,并且每个子级的级别是根据其递归父级计算的。每个孩子可能还有另一个孩子,依此类推。所以考虑这个来计算顶级权重。

架构是这样的:

CREATE TABLE TASK
(
    task_id     int IDENTITY(1,1) PRIMARY KEY,
    task_name   varchar(100),
    task_weight float,
    task_parent int
);

数据是这样的:

SET IDENTITY_INSERT [task] ON;
INSERT INTO task (task_id,task_name,task_weight,task_parent) VALUES
(1,'t1',null,null),
(2,'t2',null,1),
(3,'t3',0.03,1),
(4,'t4',0.04,2),
(5,'t5',0.03,2),
(6,'t6',null,null),
(7,'t7',0.01,6);
SET IDENTITY_INSERT [task] OFF;

我期望这样的结果(请考虑顺序)

任务名称 任务权重 级别
t1 0.10 1
__t2 0.07 2
____t4 0.04 3
____t5 0.03 3
__t3 0.03 2
t6 0.01 1
__t7 0.01 2
sql sql-server common-table-expression
1个回答
0
投票
with r as (
    select 1 as level, task_id, task_name,
        cast(0 as decimal(3, 2)) as task_weight,
        cast(task_name as varchar(max)) as task_chain
    from task
    where task_parent is null
    union all
    select level + 1, t.task_id, t.task_name,
        t.task_weight, concat(r.task_chain, '>', t.task_name)
    from task t inner join r on r.task_id = t.task_parent
)
select
    concat(replicate('__', level - 1), r.task_name) as task_name,
    cumulative_weight as weight, level
from r cross apply (
    select sum(task_weight) from r r2
    where r2.task_chain like concat('%', r.task_chain, '%')
) as s(cumulative_weight)
order by weight desc;

https://dbfiddle.uk/RVmuN4C3

© www.soinside.com 2019 - 2024. All rights reserved.