興味深い問題があります。少なくともそう思います。したがって、上記の構造を持つテーブル (codes_table) があります (これはツリー メニューです)。ツリーは、2 つの整数と (常に) 次のようなドット パターンによって定義されます。
COD_MENU NAME
01. Biggest Node
01.01. Sun of 01.
01.01.01. Sun of 01.01.
01.01.01.01. Sun of 01.01.01.
01.01.01.02. Sun of 01.01.01.
01.01.01.03. Sun of 01.01.01.
01.01.01.04. Sun of 01.01.01.
01.01.01.05. Sun of 01.01.01.
01.02. Sun of 01.
01.03. Sun of 01.
01.03.01. Sun of 01.03.
(etc...)
私が必要とするのは、次のような新しい構造の名前として実際の COD_MENU を入れて、その父へのキーをフォアイングする数値 ID を持つ構造を持つ新しいテーブルに挿入スクリプトを生成することです。
ID FATHER_ID NAME
1 NULL 01.
2 1 01.01.
3 2 01.01.01.
4 3 01.01.01.01.
5 3 01.01.01.02.
6 3 01.01.01.03.
7 3 01.01.01.04.
8 3 01.01.01.05.
9 1 01.02.
10 1 01.03.
11 10 01.03.01.
これは、再帰的な手順を使用して plsql ブロック コードで既に実行しています。上記は参照用の私の実際のコードです。
declare
auxId integer;
procedure findNodes( pCod varchar2, pCurrId in out integer, pFatherId in integer ) is
ctHasSuns integer;
father varchar2(20);
idFhtTmp integer;
begin
idFhtTmp := pFatherId;
if idFhtTmp is null then
father := 'null';
else
father := idFhtTmp;
end if;
ctHasSuns := 0;
SELECT count(cod_menu) into ctHasSuns FROM codes_table where SUBSTR (cod_menu, 1,LENGTH (cod_menu) - 3) = pCod and rownum < 10;
if (ctHasSuns > 0 or pCurrId = 1) then
dbms_output.put_line ('insert into newtable ( id, idfather, menu ) values ( '||pCurrId||','||father||', '''||pCod||''' );');
idFhtTmp := pCurrId;
for cHasSuns in ( SELECT cod_menu FROM codes_table where SUBSTR (cod_menu, 1,LENGTH (cod_menu) - 3) = pCod and rownum < 10 order by cod_menu) loop
pCurrId := pCurrId + 1;
findNodes( cHasSuns.cod_menu, pCurrId, idFhtTmp );
end loop;
else
dbms_output.put_line ('insert into newtable ( id, idfather, menu ) values ( '||pCurrId||','||father||', '''||pCod||''' );');
end if;
end;
begin
auxId := 1;
findNodes( '01.', auxId, null );
end;
私がやろうとしているのは、CONNECT BY / START WITH / ROWNUM および LEVEL ステートメントを使用して単一のクエリでそれを達成し、必要に応じて同じテーブルとの結合を使用することです。いろいろ試しましたが、解決策が思いつきませんでした。これは単なる好奇心です。
私ができる最も近いことは上記の選択ですが、太陽ではなく父親のIDを持っているだけです
WITH q AS (
select rownum id, father from (
select a.noh father, count(*)
from (select cod_menu noh, substr( cod_menu, 1, length(cod_menu)-3) as nofather from codes_table) a,
(select cod_menu noh, substr( cod_menu, 1, length(cod_menu)-3) as nofather from codes_table) b
where a.noh = b.nofather
group by a.noh
having count(*) > 0
order by a.noh)
),
b as (
SELECT cod_menu filho, father
FROM (select cod_menu, substr( cod_menu, 1, length(cod_menu)-3) as father from codes_table)
START WITH father is null
CONNECT BY prior cod_menu = father
ORDER BY cod_menu
)
SELECT * FROM q, b where q.father = b.father;
お時間をいただき、ありがとうございました。