规范化逻辑层次结构的度量的和

时间:2012-12-07 14:32:42

标签: sql recursion teradata

假设有下表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)父母可以有多个孩子(name2有name4,name5有孩子);
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次)。理想情况下,查询应该只读取每个名称的度量标准一次。

1 个答案:

答案 0 :(得分: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以递归方式联系Child&给定RootValue的度量标准值。

鉴于此CTE,所需的输出只是在RootValue列上聚合的问题。