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)親は複数の子を持つことができます(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またはTeradataSQLである必要があります。

指定された名前のすべての子孫の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;  

このクエリを、名前を引数として取り、この合計を返す関数に変換して、このように呼び出すことができるようにする方法はありますか?

SELECT Sum_Of_Descendants (Child) FROM Table1;

上記の方法が実装可能であっても、パフォーマンスが低下するため、別の角度からこれにアプローチする方法についての提案も歓迎されます-メトリックの読み取りが何度も繰り返されます(値fは3で読み取られます)この例では回)。理想的には、クエリは各名前のメトリックを1回だけ読み取る必要があります。

4

1 に答える 1

1

編集:この回答は、共通テーブル式がサポートされているSQLServer2005以降に適用されます。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定義には、子とメトリックに加えてRootValue列があります。CTEは、特定のRootValueの子とメトリックの値を再帰的に関連付けます。

このCTEが与えられると、必要な出力はRootValue列に集約するだけの問題です。

于 2012-12-10T22:15:25.993 に答える