2017-08-16 24 views
0

私は顧客、小売業者、FSE、distのサブDISTのすべての詳細を持っている一つのマスターテーブルを持っています。 iは階層 CUSTを設計する必要がある(1) - > RET(2) - > FSE(3) - > DIST(4) - >サブDIST(5) テーブル master_table:階層クエリ

id cust_mobile type 
1  9000230003 cust 
2  8906784566 ret 
3  7474747474 dist 
4  4595274646 sdist 
5  8588585958 fse 
6  8588775958 cust 
8  8588777758 dist 

link_table

id parent_id 
1  2 
2  8 
3  7 
4  5 
6  3 

私は1つの顧客IDに関連付けられているすべてのレベルを望ん

1,9000230003,cust,2,8906784566,ret,8,8588777758,dist 
6 8588775958 cust,3,7474747474,dist 

として出力する必要があります。

+0

私は、複数のループと自己加入を使用してそれを行っている、私はあなたがする必要がある –

+2

によって接続するか、レベル使用してそれを実行する必要があり期待される出力をより良く説明する。なぜ結果にあなたが提供したデータがありますか? –

+0

1,9000230003、カスト、8,8588777758、ret6 8588775958カスト、2,8906784566、RET、4,4595274646、sdistの、5,8588585958、FSE –

答えて

0

私は本当に@Alexプールからのソリューションが優れていると私はそれを投票することを理解しています。私は、ハードコーディングされたクエリを追加したいという

コードSYS_CONNECT_BY_PATHを使用して:

with t1 as (
    select 1 as id, 9000230003 as cust_mobile, 'cust' as type from dual 
    union all 
    select 2 as id, 8906784566 as cust_mobile, 'ret' as type from dual 
    union all 
    select 3 as id, 7474747474 as cust_mobile, 'dist' as type from dual 
    union all 
    select 4 as id, 4595274646 as cust_mobile, 'sdist' as type from dual 
    union all 
    select 5 as id, 8588585958 as cust_mobile, 'fse' as type from dual 
    union all 
    select 6 as id, 8588775958 as cust_mobile, 'cust' as type from dual 
    union all 
    select 8 as id, 8588777758 as cust_mobile, 'dist' as type from dual 
    ), 
    lt as (
    select 1 as id_, 2 as parent_id from dual 
    union all 
    select 2 as id_, 8 as parent_id from dual 
    union all 
    select 3 as id_, 7 as parent_id from dual 
    union all 
    select 4 as id_, 5 as parent_id from dual 
    union all 
    select 6 as id_, 3 as parent_id from dual 
    ) 
    select replace(path,', ',',') 
    from (
     select CONNECT_BY_ISLEAF as leaf, substr(SYS_CONNECT_BY_PATH(t2.id || ',' || t2.cust_mobile || ',' || t2.type, ', '),3) as path 
     from 
     ( 
      select t1.*, lt.parent_id 
      from t1 left join lt on t1.id = lt.id_ 
     ) t2 
     start with t2.type = 'cust' 
     connect by t2.id = prior t2.parent_id 
    ) t3 
    where t3.leaf = 1 

結果:

1,9000230003,cust,2,8906784566,ret,8,8588777758,dist 
6,8588775958,cust,3,7474747474,dist 
+0

いいえ、私は1人の親が2と2親であると仮定し、これを必要としません4それから私は、2,2_mob_no、4,4_mob_no –

+0

@sheetalvermaを1,1_mob_noを必要としている - 適切にあなたが必要なものを説明するために、(https://stackoverflow.com/posts/45707688/edit)[あなたの質問を編集します]。これにより、あなたが望む出力が得られます。あなたは「ID 1から始まる」と言っていませんでした。 –

1

あなたが一緒に最初にあなたのテーブルを結合した場合:

select mt.id, mt.cust_mobile, mt.type, lt.parent_id 
from master_table mt 
left join link_table lt on lt.id = mt.id; 

     ID CUST_MOBIL TYPE PARENT_ID 
---------- ---------- ----- ---------- 
     1 9000230003 cust   2 
     2 8906784566 ret   8 
     3 7474747474 dist   7 
     4 4595274646 sdist   5 
     6 8588775958 cust   3 
     5 8588585958 fse    
     8 8588777758 dist    

あなたを次いで任意から始まる、インライン・ビューまたはCTEのように、それに対して階層クエリを使用することができ3210エントリ:

with cte (id, cust_mobile, type, parent_id) as (
    select mt.id, mt.cust_mobile, mt.type, lt.parent_id 
    from master_table mt 
    left join link_table lt on lt.id = mt.id 
) 
select listagg(id ||','|| cust_mobile ||','|| type, ',') 
    within group (order by level) as result 
from cte 
start with type = 'cust' 
connect by id = prior parent_id 
group by connect_by_root(id); 

RESULT                   
-------------------------------------------------------------------------------- 
1,9000230003,cust,2,8906784566,ret,8,8588777758,dist 
6,8588775958,cust,3,7474747474,dist 

これは、各行の関連するデータをコンマで区切られた単一の値に連結します。それらの結合されたエントリのそれぞれは、listagg()を使用して単一の結果に入れられます。

楽しみのためだけに、あなたも(11gR2のから)再帰CTEを使用することができます。ここで私はちょうどlistagg()からそれを分離するために、CTE内の最初の連結を移動しました:

with rcte (id, id_mobile_type, root_id, hop) as (
    select mt.id, mt.id ||','|| mt.cust_mobile ||','|| mt.type, mt.id, 1 
    from master_table mt 
    where mt.type = 'cust' -- starting condition 
    union all 
    select mt.id, mt.id ||','|| mt.cust_mobile ||','|| mt.type, 
    rcte.root_id, rcte.hop + 1 
    from rcte 
    join link_table lt on lt.id = rcte.id 
    join master_table mt on mt.id = lt.parent_id 
) 
select listagg(id_mobile_type, ',') within group (order by hop) as result 
from rcte 
group by root_id; 

RESULT                   
-------------------------------------------------------------------------------- 
1,9000230003,cust,2,8906784566,ret,8,8588777758,dist 
6,8588775958,cust,3,7474747474,dist