3

假设有一个下表Table1,描述了父子关系和度量:

Parent | Child | Metric (of a child)
------------------------------------
name0 | name1 | a  
name0 | name2 | b  
name1 | name3 | c  
name2 | name4 | d  
name2 | name5 | e  
name3 | name6 | f

特点:
1)孩子总是只有1个父母;
2)Parent可以有多个children(name2有name4和name5作为children);
3)这个“层次结构”中的级别数和任何给定父级的子级数是任意的,并且不相互依赖;

我需要 SQL 请求,该请求将返回结果集,其中包含每个名称及其 所有后代的度量总和,直至底层加上自身,因此对于此示例表,结果将是(仔细查看name1):

Name | Metric
------------------
name1 | a + c + f  
name2 | b + d + e  
name3 | c + f  
name4 | d  
name5 | e  
name6 | f

(name0 无关紧要,可以排除)。

它应该是 ANSI 或 Teradata SQL。

我得到了一个递归查询,它可以返回给定名称的所有后代的 SUM(度量):

WITH RECURSIVE temp_table (Child, metric) AS
(  
   SELECT root.Child, root.metric  
   FROM table1 root  
   WHERE root.Child = 'name1'  
   UNION ALL  
   SELECT indirect.Child, indirect.metric  
   FROM temp_table direct, table1 indirect  
   WHERE direct.Child = indirect.Parent
)  
SELECT SUM(metric) FROM temp_table;  

有没有办法把这个查询变成一个以 name 作为参数并返回这个总和的函数,所以它可以这样调用?

SELECT Sum_Of_Descendants (Child) FROM Table1;

任何关于如何从不同角度解决此问题的建议也将不胜感激,因为即使上述方式是可实施的,它的性能也会很差 - 读取指标会有很多迭代(值 f 将被读取 3本例中的次数)。理想情况下,查询应该只读取每个名称的度量一次。

4

1 回答 1

1

编辑:此答案适用于支持公用表表达式的 SQL Server 2005 及更高版本。teradata我第一次回答问题时没有注意标签。希望这个答案仍然相关,因为语法似乎几乎相同。

这可以在 SQL Server 中通过将每个级别的层次结构扩展为

with recursive temp_table (RootValue, Child, Metric)
as 
(select
    root.Child, root.Child, root.Metric
from table1 root
union all
select
    direct.RootValue, indirect.Child, indirect.Metric
from temp_table direct join table1 indirect on indirect.Parent = direct.Child
)
select
    RootValue, SUM(Metric)
from temp_table
group by RootValue;

(公用表表达式)CTE 定义除了 Child 和 Metric 之外还有一个 RootValue 列。CTE 递归地关联给定 RootValue 的 Child & Metric 值。

鉴于此 CTE,所需的输出只是对 RootValue 列进行聚合的问题。

于 2012-12-10T22:15:25.993 回答