8

Oracle には、非常に便利な機能が付属しています。次の句を使用して、階層クエリ (再帰動作) を作成できます。

CONNECT BY [NOCYCLE] {condition [AND condition...]} [START WITH condition]

ここに文書化されているように:

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/queries003.htm

同等または類似の構文をサポートする他の確立された RDBMS はありますか? または、このような再帰的な動作は、通常の SQL を使用して一般的にシミュレートできますか?

シミュレートできるようにしたい良い例は次のとおりです (Oracle のドキュメントから取得)。

    SELECT LPAD(' ', 2 * (LEVEL-1)) || last_name org_chart, 
           employee_id, manager_id, job_id
      FROM employees
START WITH job_id = 'AD_VP' 
CONNECT BY PRIOR employee_id = manager_id; 

その結果:

ORG_CHART          EMPLOYEE_ID MANAGER_ID JOB_ID
------------------ ----------- ---------- ----------
Kochhar                    101        100 AD_VP
  Greenberg                108        101 FI_MGR
    Faviet                 109        108 FI_ACCOUNT
    Chen                   110        108 FI_ACCOUNT
    Sciarra                111        108 FI_ACCOUNT
    Urman                  112        108 FI_ACCOUNT
    Popp                   113        108 FI_ACCOUNT
  Whalen                   200        101 AD_ASST
  Mavris                   203        101 HR_REP
  Baer                     204        101 PR_REP
  Higgins                  205        101 AC_MGR
    Gietz                  206        205 AC_ACCOUNT
De Haan                    102        100 AD_VP
  Hunold                   103        102 IT_PROG
    Ernst                  104        103 IT_PROG
    Austin                 105        103 IT_PROG
    Pataballa              106        103 IT_PROG
    Lorentz                107        103 IT_PROG

疑似列とそれLEVELで達成されるインデントは、私にとってそれほど重要ではありません

4

3 に答える 3

5

SQL Serverは、共通テーブル式(WITHステートメント)を使用して同じことを実現します(共通テーブル式を使用した再帰クエリを参照)。

この種のクエリは、Oracleでも使用できます(間違っていない場合は11gから開始します)。

結果のクエリはより複雑です。

WITH emp(employee_id, manager_id, job_id, last_name, lvl)
AS (
    SELECT e.employee_id, e.manager_id, e.job_id, e.last_name, 1 lvl
    FROM employees e
    WHERE job_id = 'AD_VP'
    UNION ALL
    SELECT e.employee_id, e.manager_id, e.job_id, e.last_name, r.lvl + 1 lvl
    FROM employees e
    JOIN emp r ON r.employee_id = e.manager_id
)
SELECT LPAD(' ', 2 * (lvl-1)) || last_name org_chart,
    employee_id, manager_id, job_id
FROM emp;
于 2011-06-19T08:17:28.873 に答える
4

developerworks サイトのPort CONNECT BY to DB2には、優れた変換を行う記事があります。また、Explain Extended (Quassnoi のブログ) に関する興味深い記事では、CONNECT BY と再帰的 CTE の違いを示しています: Adjacency list vs. nested sets: Oracle、行ベースとセットベースです。彼はまた、「SQL Server: 再帰 CTE は本当にセットベースですか?」についての素晴らしい記事を書いています。「Oracleの再帰CTEも設定ベースではない」ようです。これが変換、JOOQ での再帰、および SQL での再帰の両方の実装の違いの理解に役立つことを願っています。

よろしく、JJ。

于 2012-03-04T00:51:26.410 に答える
2

SO をトロールすると、さまざまなデータベースに対する階層クエリを処理する次の質問と回答が示されました。これらの最後のものは、一般的な SQL アプローチを提供するMySql リソースを参照します。

再帰クエリを使用してテーブル依存関係グラフを作成する

SQL での再帰選択

SQL 再帰クエリ

MySQL の階層データから深さベースのツリーを生成する (CTE なし)

于 2011-06-19T08:54:41.413 に答える