SQL - 从分层子代设置值

时间:2015-04-18 19:09:48

标签: sql hierarchical-data

我正在编写一个应用程序,它从项目规划MS SQL表中获取任务数据(让我们调用表tasks)。为简单起见,表字段可以被认为如下:

task_id, parent_id, name, start_date, end_date

所有父任务都有NULL作为开始日期和结束日期。只有孩子(没有自己的孩子)有开始和结束日期。

我想获取任务数据,并在此过程中根据所有父母的子女和递归孙子的最早开始日期设置每个父母的开始日期,并将结束日期设置为所有孩子的最后结束日期和递归的孙子。这可能吗?

1 个答案:

答案 0 :(得分:1)

我假设您使用Sql Server。我想这就是你想要的。它使用递归公用表表达式完成。它始于叶子儿,并且最多的父母是最重要的:

DECLARE @t TABLE(id INT, pid INT, sd DATE, ed DATE)

INSERT INTO @t VALUES
(1, NULL, NULL, NULL),
(2, 1, NULL, NULL),
(3, 2, '20150201', '20150215'),
(4, 2, '20150101', '20150201'),
(5, 1, NULL, NULL),
(6, 5, '20150301', '20150401'),
(7, 1, NULL, NULL),
(8, 7, NULL, NULL),
(9, 8, '20140101', '20141230'),
(10, 8, '20140102', '20141231')

;WITH cte AS(
SELECT * FROM @t WHERE sd IS NOT NULL

UNION ALL

SELECT t.id, t.pid, c.sd, c.ed FROM @t t
JOIN cte c ON c.pid = t.id
)

SELECT id, pid, MIN(sd) AS sd, MAX(ed) AS ed 
FROM cte
GROUP BY id, pid
ORDER BY id

输出:

id  pid   sd            ed
1   NULL  2014-01-01    2015-04-01
2   1     2015-01-01    2015-02-15
3   2     2015-02-01    2015-02-15
4   2     2015-01-01    2015-02-01
5   1     2015-03-01    2015-04-01
6   5     2015-03-01    2015-04-01
7   1     2014-01-01    2014-12-31
8   7     2014-01-01    2014-12-31
9   8     2014-01-01    2014-12-30
10  8     2014-01-02    2014-12-31