2

レポート構造を追跡するための階層クエリがあります。これはほとんど機能しますが、最上位のノードをレポートしていない場合を除きます。おそらく、最上位のユーザーが自分自身に「レポート」しているためです。

クエリは次のとおりです。

select
  level,
  empid, 
  parentid
from usertable
connect by nocycle prior parentid= empid
start with empid = 50

これにより、次のものが生成されます。

LEVEL  EMPID PARENTID               
------ ----- --------  
1      50    258            
2      258   9555
3      9555  17839

次のようになるため、レベル4を取得していません。

4      17839 17839

データを変更せずに、4つのレベルすべてが返されるようにクエリを変更する方法はありますか?目標は、empidsを取得することです。これにより、次のチェックを行うことができます。

id in (hierarchical subquery)

ところで、クエリからnocycleを削除すると、エラーが発生します。

4

5 に答える 5

5

クリス、

最上位の行が階層クエリを処理する方法に設定されていないため、3行しか取得できません。通常、最上位の行、またはOracleのよく知られているEMPテーブルのKING社長には、マネージャーがいません。あなたの場合、17389の親IDを17389自体に設定するのではなく、NULLに設定する必要があります。それに応じてテーブルを更新するか、ビューを使用してこの状況に対応してください。

例:

SQL> select empno
  2       , mgr
  3    from emp
  4   where empno in (7876,7788,7566,7839)
  5  /

     EMPNO        MGR
---------- ----------
      7566       7839
      7788       7566
      7839       7839
      7876       7788

4 rijen zijn geselecteerd.

EMP表のこの部分には、最上位行(7839)がそれ自体に設定された4つのレベルがあります。empid 17839と同じです。これにより、クエリを使用すると3行のみになります。

SQL>  select level
  2        , empno
  3        , mgr
  4     from emp
  5  connect by nocycle prior mgr = empno
  6    start with empno = 7876
  7  /

     LEVEL      EMPNO        MGR
---------- ---------- ----------
         1       7876       7788
         2       7788       7566
         3       7566       7839

3 rijen zijn geselecteerd.

(インライン)ビューを使用して、最上位レベルのmgr/parentid列をnullに設定します。

SQL>  select level
  2        , empno
  3        , mgr
  4     from ( select empno
  5                 , nullif(mgr,empno) mgr
  6              from emp
  7          )
  8  connect by nocycle prior mgr = empno
  9    start with empno = 7876
 10  /

     LEVEL      EMPNO        MGR
---------- ---------- ----------
         1       7876       7788
         2       7788       7566
         3       7566       7839
         4       7839

4 rijen zijn geselecteerd.

または、UPDATEステートメントを使用してデータを修正します。

SQL> update emp
  2     set mgr = null
  3   where empno = 7839
  4  /

1 rij is bijgewerkt.

SQL>  select level
  2        , empno
  3        , mgr
  4     from emp
  5  connect by nocycle prior mgr = empno
  6    start with empno = 7876
  7  /

     LEVEL      EMPNO        MGR
---------- ---------- ----------
         1       7876       7788
         2       7788       7566
         3       7566       7839
         4       7839

4 rijen zijn geselecteerd.

また、修正が完了したら、NOCYCLEキーワードを省略できます。

よろしく、ロブ。

于 2009-05-21T15:17:29.383 に答える
3

ルートからリーフまで、逆の方法で階層を作成する必要があります。

select
  level,
  empid, 
  parentid
from usertable
start with empid = 17839
connect by empid != 17839 and prior empid = parentid

LEVEL                  EMPID                  PARENTID               
---------------------- ---------------------- ---------------------- 
1                      17839                  17839                  
2                      9555                   17839                  
3                      258                    9555                   
4                      50                     258                    

4 rows selected
于 2009-05-21T14:30:17.670 に答える
1

構造を変更する必要はありません。

次のクエリを使用するだけです

select
  level,
  empid,
  parentid
from usertable
connect by prior parentid = empid
       AND parentid <> empid  -- This line prohibits cycling and ALLOWS a row where parentid = empid
start with empid = 50
于 2010-12-10T09:44:45.457 に答える
1

Van Heddegem Roelandの答えは私にはうまくいきません、私はすでにそれを試しました、しかし私は次を追加することによって、connect節でインラインビューなしでそれを行うことができました:-

and prior empid <> parentid

次の投稿は、それが機能する理由を説明しています-頭を回すことができれば!'get it'を実行すると、論理的には理にかなっていますが。(これは、<>演算子の両側の評価の順序と関係があります。)

Oracle:ユーザーデータのConnect By Loop

インラインビューは機能しますが、特定のデータセットを調査しないと、インラインビューがクエリパスにどのような影響を与える可能性があるかわかりません。余分な句を追加することは、おそらくほとんどの状況でそれを行うための「正しい」方法です、私見。

于 2016-01-06T10:51:08.683 に答える
-1

データにサイクルがあるようです。「nocycle」がないと、すぐには機能しません。すべてのデータのネストレベルが最大4であることがわかっている場合は、条件「およびレベル<= 4」を追加して、nocycleを削除できます。動作するはずです。

于 2009-05-21T14:32:52.920 に答える