我遇到了一个问题,我希望以递归方式从树中聚合数据。例如,我的任务列表如下所示:
CREATE TABLE tasks (
id int,
parentid int,
name varchar(256),
status varchar(32),
completiondate varchar(32),
startdate varchar(32)
);
INSERT INTO tasks VALUES (1, NULL, 'clean', NULL, NULL, NULL)
INSERT INTO tasks VALUES (2, NULL, 'wash', NULL, NULL, NULL)
-- insert subtasks
INSERT INTO tasks VALUES (3, 1, 'vacuum', NULL, NULL, NULL)
INSERT INTO tasks VALUES (4, 3, 'vacuum floor', 'completed', '2013-12-01', '2013-12-01')
INSERT INTO tasks VALUES (5, 3, 'vacuum stairs', 'not done', NULL, NULL)
INSERT INTO tasks VALUES (6, 1, 'windows', 'completed', '2014-02-01', '2014-01-01')
INSERT INTO tasks VALUES (7, 2, 'white clothes', 'completed', '2014-02-01', '2014-01-01')
INSERT INTO tasks VALUES (8, 2, 'colored clothes', 'completed', '2014-02-01', '2014-01-01')
我希望id 3的任务如下:
id name status completiondate startdate
3 vacuum 'not done' NULL '2013-12-01'
并且此结果将汇总到id 1:
id name status completiondate startdate
1 clean 'not done' NULL '2013-12-01'
和id 2:
id name status completiondate startdate
2 wash 'completed' '2014-02-01' '2014-01-01'
逻辑是,如果所有"子任务" (子)已完成状态,然后取MAX(completiondate)
,否则为null。并且startdate将是所有孩子的MIN(startdate)
。
有没有人知道如何进行?我尝试了一个递归的CTE,但它并没有那么顺利。它可以达到几个级别,所以我想我必须从底部开始汇总?
祝你好运
答案 0 :(得分:1)
递归CTE和一些有创意的SUM():
;with x as (
select *, id as root_id, name as root_name
from tasks
--where parentid is null
where id = 3
union all
select t.*, x.root_id, x.root_name
from tasks t
inner join x on t.parentid=x.id
),
y as (
select root_id, root_name, sum(case when status='not done' then 1 else 0 end) as status,
min(startdate) AS startdate, max(completiondate) AS completiondate
from x
group by root_id, root_name
)
select root_id, root_name, case when status = 0 then 'completed' else 'not done'end as status,
startdate, case when status = 0 then completiondate else null end
from y