1

私はテーブルを持っています、SELECT * FROM data

id   pred   name        visual link, for your convenience
--------------------
 1   null   One              
20   null   Two         <--+
21     20   Three         -^
30   null   Four              <--+      
31     30   Five                -^  <--+ 
32     31   Six                       -^  

行は、列を介してpred列に接続されていidます。それらはチェーンのみを形成し、ツリーは形成しません。各ノードには、1 つまたは 0 つの後続ノードしかありません (重要な場合)。

initチェーンの最初の要素が表示されるクエリに列を追加したい、つまり

id   pred   name    init initname
---------------------------------
 1   null   One        1 One
20   null   Two       20 Two
21     20   Three     20 Two
30   null   Four      30 Four
31     30   Five      30 Four
32     31   Six       30 Four
  • pred=nullの行も表示nullされれば問題ありませんinit
  • このinitname列は完全にオプションです。ここではデモンストレーションのためにのみ示します。必要なのはid.

について収集しconnect byことから、「ルート」ごとにその「子」ノードがリストされているという、やや逆の結果を管理しました。「クエリを好転させる」方法がわかりません。

SELECT id, pred, CONNECT_BY_ROOT id init, LEVEL, CONNECT_BY_ISLEAF "IsLeaf"
FROM data
CONNECT BY PRIOR pred=id
ORDER BY id, level;

結果を与える

id  pred   init lvl isLeaf
--------------------------
1   null    1   1   1
20  null    20  1   1
20  null    21  2   1
21  20      21  1   0
30  null    30  1   1
30  null    31  2   1
30  null    32  3   1
31  30      31  1   0
31  30      32  2   0
32  31      32  1   0

明らかに、「ツリー」全体を何らかの形で表しています。しかし、悲しいかな、「間違った方法」です。たとえば、

id  pred  init lvl isLeaf
21   20    0     ?   ?

それ以外の

id  pred init lvl isLeaf
21   20   21   1     0

データが必要な場合は、サンプル データを次に示します。

create table data ( id number primary key, pred number, name varchar2(100) );
insert into data(id,pred,name) values(     1 ,  null  , 'One');
insert into data(id,pred,name) values(    20,   null  , 'Two');
insert into data(id,pred,name) values(21,     20  , 'Three');
insert into data(id,pred,name) values(30,   null ,  'Four');
insert into data(id,pred,name) values(31,     30 ,  'Five');
insert into data(id,pred,name) values(32,     31 ,  'Six');
4

3 に答える 3

1

ルート要素の名前を取得するには、次の式を使用してみてください:

substr(SYS_CONNECT_BY_PATH(name, '/'), instr(SYS_CONNECT_BY_PATH(name, '/'), '/', -1)+1)

必要に応じて区切り文字「/」を置き換えます。

SELECT id, pred, CONNECT_BY_ROOT id init, LEVEL, CONNECT_BY_ISLEAF "IsLeaf", 
       substr(SYS_CONNECT_BY_PATH(name, '/'), instr(SYS_CONNECT_BY_PATH(name, '/'), '/', -1)+1)
FROM data
CONNECT BY PRIOR pred=id
--    START WITH pred is NULL --???
ORDER BY id, level;

おそらく START WITH 句も追加する必要があります

于 2014-09-26T08:44:44.957 に答える
0

ネストされたクエリで結果を得ることができました。

select id, pred, name, init, (select name from data where id=init) initname
from (
    SELECT d1.*
      , (select d2.id init
           from data d2
         where CONNECT_BY_ISLEAF=1 start with d2.id=d1.id CONNECT BY PRIOR pred=id) init
    FROM data d1
    ORDER BY id ) xdata
;

ご覧のとおり、initnameI need a additional subquery を取得するには、このようにします。これは完全ではありませんが、十分です。クエリは PK にあります。

id pred Name    init initname
------------------------------
1       One     1    One
20      Two     20   Two
21  20  Three   20   Two
30      Four    30   Four
31  30  Five    30   Four
32  31  Six     30   Four
于 2014-09-29T08:08:18.273 に答える