4

次のようなツリー構造を表す Oracle 10g のテーブル MYTYPE があります。

ID | PARENTID | DETAIL

特定の ID の子孫である MYTYPE 内のすべての行を選択して、次のようなクエリを他の場所で作成できるようにしたいと考えています。

SELECT * 
  FROM MYDETAIL 
 WHERE MYTYPEID IN [all MYTYPE which are descendants of some ID];

できればPL/SQLを使用せずに、子孫セットを構築する費用効率の高い方法は何ですか?

4

4 に答える 4

9

Oracle は、11g R2 まで、再帰的なサブクエリ ファクタリング (SQL Server 構文の CTE) を使用する ANSI 階層構文をサポートしていなかったため、Oracle のネイティブ CONNECT BY 構文 (v2 以降でサポート) を使用する必要があります。

   SELECT t.*
      FROM MYTABLE t
START WITH t.parentid = ?
CONNECT BY PRIOR t.id = t.parentid

疑問符を、階層データを検索する親に置き換えます。

参照:

于 2011-01-17T20:20:58.313 に答える
2

ID,ParentIDRDBMS で列を使用して階層データを管理することは、隣接リストモデルとして知られています。実装と保守 (つまり、挿入、更新、削除) は非常に簡単ですが、リネ​​ージ (つまり、先祖と子孫) を特定するにはコストがかかります。他の回答がすでに書いているように、OracleCONNECT BYは機能しますが、これは高価な操作です。データを別の方法で表現した方がよい場合があります。

あなたの場合、最も簡単な解決策は、 Hierarchy Bridgeテーブルと呼ばれるものをスキーマに追加LEVELし、元のテーブルに列を追加することです。テーブルには列ID,DescendantIDがあり、ID で選択するとすべての子孫レコードが表示され、DescentantID で選択するとすべての先祖レコードが表示されます。LEVELレコードを並べ替えるには、ベース テーブルで必要です。このようにして、高価な更新と安価な読み取りのトレードオフを行います。これは、あなたの質問があなたが望んでいることを意味します。

ベース データの変更に関連するその他の可能性には、ネストされたセットとマテリアライズド パスの表現が含まれます。これは、はるかに安価な読み取りに対して、より高価な書き込みの同様のトレードオフを提供します。オプション、長所と短所の完全なリスト、および実装に関する注意事項については、このトピックに関する以前の質問を参照してください

于 2011-01-18T11:27:49.700 に答える
1

Oracleの「接続方法」機能の詳細は次のとおりです。 http://psoug.org/reference/connectby.html

于 2013-02-01T06:12:09.323 に答える
1

Oracle は再帰クエリを実行できます。start with ... connect by次のようなものを調べてみてください。

Select *
from MYDETAIL
Starting with PARENTID= 1 --or whatever the root ID is
connect by PARENTID = prior ID

http://psoug.org/reference/connectby.html

于 2011-01-17T20:21:17.050 に答える