1

を含むテーブル Test があります

TEST
----
tablename|columnvalue|rankofcolumn
A|C1|1
A|C2|2
A|C3|3
A|C4|4
B|CX1|1
B|CX2|2
C|CY1|1
C|CY2|2
C|CY3|3

次のように、他の列と一緒にパスを生成したい

RESULT
----
tablename|columnvalue|rankofcolumn|path
A|C1|1|C1
A|C2|2|C1->C2
A|C3|3|C1->C2->C3
A|C4|4|C1->C2->C3->C4
B|CX1|1|CX1
B|CX2|2|CX1->CX2
C|CY1|1|CY1
C|CY2|2|CY1->CY2
C|CY3|3|CY1->CY2->CY3

この質問に従って、再帰 CTE を使用してこれを達成できます

WITH r ( tablename, columnvalue, rankofcolumn, PATH ) AS
         (SELECT    tablename,
                    columnvalue,
                    rankofcolumn,
                    columnvalue
          FROM      test
          WHERE     rankofcolumn = 1
          UNION ALL
          SELECT    xx.tablename,
                    xx.columnvalue,
                    xx.rankofcolumn,
                    r.PATH || '->' || xx.columnvalue
          FROM      r
                    JOIN test xx
                        ON     xx.tablename = r.tablename
                           AND xx.rankofcolumn = r.rankofcolumn + 1)
SELECT    *
FROM      r;

しかし、現時点ではこのオプションがない WX2 データベースを使用しています。これに代わる SQL はありますか?

4

1 に答える 1

2

徐々にデータを入力するテーブルを使用して、ブルート フォース アプローチを実行できます。testテーブルが次のようになっていると仮定します。

create table test (tablename varchar2(9), columnvalue varchar2(11), rankofcolumn number);

次に、resultテーブルを次のように作成できます。

create table result (tablename varchar2(9), columnvalue varchar2(11), rankofcolumn number,
  path varchar2(50));

次に、最低ランクの結果エントリを作成します。

insert into result (tablename, columnvalue, rankofcolumn, path)
select t.tablename, t.columnvalue, t.rankofcolumn, t.columnvalue
from test t
where t.rankofcolumn = 1;

3 rows inserted.

そして、既存の最高ランクに基づいて行を繰り返し追加し、テーブルから次の値を取得します (その値がある場合tablename) 。test

insert into result (tablename, columnvalue, rankofcolumn, path)
select t.tablename, t.columnvalue, t.rankofcolumn,
  concat(concat(r.path, '->'), t.columnvalue)
from test t
join result r
on r.tablename = t.tablename
and r.rankofcolumn = t.rankofcolumn - 1
where t.rankofcolumn = 2;

3 rows inserted.

insert into result (tablename, columnvalue, rankofcolumn, path)
select t.tablename, t.columnvalue, t.rankofcolumn,
  concat(concat(r.path, '->'), t.columnvalue)
from test t
join result r
on r.tablename = t.tablename
and r.rankofcolumn = t.rankofcolumn - 1
where t.rankofcolumn = 3;

2 rows inserted.

insert into result (tablename, columnvalue, rankofcolumn, path)
select t.tablename, t.columnvalue, t.rankofcolumn,
  concat(concat(r.path, '->'), t.columnvalue)
from test t
join result r
on r.tablename = t.tablename
and r.rankofcolumn = t.rankofcolumn - 1
where t.rankofcolumn = 4;

1 row inserted.

そして、列の可能な最大数 (つまりrankofcolumn、テーブルの最大数) を続けます。WX2 では手続き的にそれを行うことができ、ゼロ行が挿入されるまで繰り返します。しかし、あなたはそれをかなり制限された音にしました。

これらすべての反復の後、テーブルには次のものが含まれるようになりました。

select * from result
order by tablename, rankofcolumn;

TABLENAME COLUMNVALUE RANKOFCOLUMN PATH                                             
--------- ----------- ------------ --------------------------------------------------
A         C1                     1 C1                                                
A         C2                     2 C1->C2                                            
A         C3                     3 C1->C2->C3                                        
A         C4                     4 C1->C2->C3->C4                                    
B         CX1                    1 CX1                                               
B         CX2                    2 CX1->CX2                                          
C         CY1                    1 CY1                                               
C         CY2                    2 CY1->CY2                                          
C         CY3                    3 CY1->CY2->CY3                                     

Oracle でテスト済みですが、Oracle 固有のものは避けようとしています。もちろん、WX2 用に微調整する必要があるかもしれません。

于 2016-04-05T12:10:59.143 に答える