2

NAME、NAME_TYPE、SOURCEを次のように格納するテーブルTABA(PK:NAME)があります。

NAME  NAME_TYPE SOURCE
----  --------- ------
Name1 Category  S1
Name2 Category  S2
Name3 Datamart  
Name4 Category  S1
Name5 Datamart
Name6 Datamart
Name7 Category  S3

上記の注:NAME_TYPE = Categoryの場合のみ、ソースがデータに存在します。

この方法でname_typeに基づくNAME列間の関係を持つNAME、PARENT_NAMEを格納する別のテーブルTABA_PARENTがあります。データマートとカテゴリの関係は1対多です。

  NAME   PARENT_NAME
    -----  -----------
    Name3  Name1
    Name3  Name2
    Name3  Name4
    Name3  Name5
    Name5  Name1
    Name5  Name6
    Name6  Name7

私の要件は、NAME_TYPE = DatamartであるTABAのSOURCEを取得することです(現在、TABAにはありません)

期待される出力:

SOURCE column for Name3
-----------------------

S1,S2,S3

秘訣は、Name3がTABA_PARENTのカテゴリにマップされるまで、Name3のSOURCEを再帰的に推測することです。

上記の例では:

Name3は、PARENT_NAME Name1、Name2、Name4、Name5にマップされます。これらのうち3つ(name1、Name2、Name4)はname_type =カテゴリであるため、TABAで個別のソースを使用できます--S1、S24番目のPARENT_NAMEName5はname_typeデータマート(ソース情報は使用できません)であり、 name_type=Categoryに到達します。

Name5がPARENT_NAMEName1、Name6にマップされているという情報があります。Name1はカテゴリであるため、ソースを推測できます。Name6もデータマートです。

ただし、Name6は最終的にカテゴリであるName7にマップされるため、ソースが利用可能です-S3

上に示したように、すべてのマッピングは、個別のソースを識別するためにname_typeCategoryに到達するまで再帰的に解決する必要があります。

Expected Result: S1,S2,S3 

これがlistaggまたは同様のものを使用して実行できるかどうかを試しています(小さなpl / sqlコードでも問題ありませんが、可能であれば単一の選択をお勧めします)これを再帰的に実行するのは困難です。どんな助けでも大歓迎です。

4

3 に答える 3

3

listagg()コメントに記載されているように、これは、Oracle 11.2 以降で利用可能なと の組み合わせで実行できますconnect by。11.2 を使用していない場合は、他にも多数の文字列集約手法を利用できます

select listagg(source, ',' ) within group ( order by source )
  from ( select distinct source
           from taba a
           join ( select parent_name
                    from taba_parent
                   start with name = 'Name3'
                 connect by prior parent_name = name
                         ) b
             on a.name = b.parent_name
                )

サブクエリdistinctが存在するのは、同じソースが複数あるためです。これは を返しますS1,S2,S3

異なる名前で同じものを取得するには、START WITH 句を変更できます。たとえば、これを return に変更しstart with name = 'Name5'ますS1,S3

データマートにソースがないという事実は、テーブルに対してのみ階層クエリを使用し、必要な情報がある場合にのみテーブルtaba_parentに結合するため、問題ではありません。taba

これは、デモンストレーションする小さなSQL Fiddleです。

于 2012-09-04T19:16:04.323 に答える
1

これを試してくれてありがとう。「connect by」とlistaggの組み合わせを使用しようとしましたが、望ましい結果が得られました。

select listagg(source,',') within group (order by source) final_source from ( 
select
distinct
b.source source--,
from taba_parent a, taba b
where b.name = a.parent_name
and b.name_type = 'Category'
connect by prior a.parent_name = a.name
start with a.name = 'Name3'        
);
于 2012-09-04T22:02:35.073 に答える
0

「究極の親」を取得するには、階層クエリ(接続)が必要です。次に、 listagg を使用してアイテムを連結する必要があります。私は Oracle 10g しか持っていないので、listagg はありません。階層ビットは次のとおりです。

select distinct source from
(
select taba_parent.name, taba_parent.parent_name, taba.source
from
taba_parent
inner join taba on taba_parent.parent_name = taba.name
)
where name in (select name from taba where name_type = 'Datamart')
connect by name = parent_name
start with source is not null

これは与える:

SOURCE
S3
S2
S1

また、listagg を使用して S3、S2、S1 を取得できます。

于 2012-09-04T19:13:08.847 に答える