5


0

階層テーブル内の重複した値や重複する値を検出しようとしています。

次の(少し工夫された)例を考えてください。

SELECT * FROM empから開始mgr IN(SELECT empno FROM emp WHERE ename = 'JONES' UNION ALL SELECT Empno FROM emp WHERE ename = 'JONES')CONNECT BY PRIOR Empno = mgr;

を返します…​

EMPNO ENAME JOB MGRがSAL COMM DEPTNOを広めました---------- ---------- --------- ---------- --- ------ ---------- ---------- ---------- 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7876 ADAMS CLERK 7788 23-MAY-87 1100 20 7902フォードアナリスト7566 03-DEC-81 3000 20 7369 SMITH CLERK 7902 17-DEC-80 800 20

私が実際に欲しいのは…​

EMPNO ENAME JOB MGRがSAL COMM DEPTNOを広めました---------- ---------- --------- ---------- --- ------ ---------- ---------- ---------- 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7876 ADAMS CLERK 7788 23-MAY-87 1100 20 7876 ADAMS CLERK 7788 23-MAY-87 1100 20 7369 SMITH CLERK 7902 17-DEC-80 800 20 7369 SMITH CLERK 7902 17-DEC-80 800 20 7902フォードアナリスト7566 03-DEC-81 3000 20 7902フォードアナリスト7566 03-DEC-81 3000 20

つまり、各行をサブクエリ内に存在する数だけ返すようにします(順序は無視します)。 START WITHはIN句を使用しているため、繰り返される値は抑制されています。 これを実行できるようにSQLを再編成することは可能ですか?

私の場合、副次句はUNIONではなく、テーブルから複数の(場合によっては重複する)値を返す可能性のあるSELECTです。

PL / SQLでは、一時テーブルに値を書き込み、次にGROUPing COUNTingを実行することでこれを実行できますが、可能な場合にのみSQLで実行することをお勧めします。

説明が必要かどうかを教えてください。

ありがとう:-)

編集:

サブクエリから返される0 …​ N個の値があるかもしれないことに注意してください。

4 Answer


3


これを試してみてください。

EMPNO、ENAME FROM、EMPNOによるカウントempグループとしてのEMPNOの選択、ENAMEのカウント(*)> 1


0


結果セットを複製する1つの方法は、それを2行の結果セットに交差結合(デカルト積)することです。

SQL> WITH your_query AS(2 SELECT object_name 3 FROM all_objects WHERE ROWNUM <= 3 4)5 SELECT your_query。* 6 FROM your_query 7 CROSS JOIN(SELECT NULL FROMデュアルUNION ALL SELECT NULL FROM dual);

OBJECT_NAME ------------------------------ IND $ IND $ ICOL $ ICOL $ OBJ $ OBJ $

あなたの場合、これはうまくいくはずです。

WITH your_query AS(SELECT * FROM emp開始WITH mgr IN(SELECT empno FROM emp WHERE ename = 'JONES')CONNECT BY PRIOR empno = mgr)your_queryを選択してください。 ;


0


最初にempから複雑な選択クエリの結果への外部結合を行い、次にそれに基づいてconnect-byクエリを作成する必要があるようです。

このような何か、多分:

WITH mgrs AS(SELECT empno FROM emp WHERE ename = 'JONES' UNION ALL SELECT empno FROM emp WHERE ename = 'JONES')、all_emps AS(SELECT emp。*、ケースmgrs.empnoがNULL以外の場合1終わりとして開始) emp左外部mgrs on mgrs.empno = emp.mgr)SELECT *からall_empsで始まるstart_with = 1で始まる最初に接続empno = mgr;


-1


とても簡単です。

_ SELECT * FROM empSTART WITH mgr IN(SELECT empno FROM emp WHERE ename = 'JONES' UNION ALL + SELECT empno FROM emp WHERE ename = 'JONES')CONNECT BY PRIOR empno = mgr; _