2009-08-26 18 views
2

私はエンティティの基本的な木構造を持っています。ツリーは最大5つのノード深度にすることができますが、Nノード幅にすることができます。私は以下の通りであるものと同様のテーブルで、この関係をマッピングしています階層SQLの質問

myID | myDescription | myParentID 

私が始まる「MYID」を有するに変換可能性が知られているオブジェクト、と出始めています。今私はすべての子ノードを取得したい。 1つのステートメントですべての子ノードを取得する方法はありますか?これには私の子供の子供たちを含める必要があり、木を下って行く必要があります。私はOracle SQLを使用しています。

おかげで、 ジェイ

答えて

4
SELECT * 
FROM mytable 
START WITH 
     myid = :id 
CONNECT BY 
     myparentid = PRIOR myid 
+0

これはOracle上でのみ正しく動作しますか? –

+0

@Eric:正しいですが、CONNECT BYはOracleのみの階層的なクエリ構文です。 –

+0

'@Eric J.':絶対に。 'SQL Server'と' PostgreSQL 8.4'では 'CTE'を' PostgreSQL 8.3-'と' MySQL'に使っています。私のブログではこれらの記事を読んでいます:http://explainextended.com/2009/05/29/hierarchical -queries-in-postgresql /、http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/ – Quassnoi

0

は、私はあなたが単一のクエリ内のすべてのノードを検索したい場合は、あなたの階層をモデル化するために別の方法を使用してお勧めします。 1つの非常に良い共通の実装はnested setモデルです。この記事では、これがMySQLでどのように実装されるかを概説しますが、簡単にOracleに移植することができます。

+0

それはクールなモデルですが、並行アップデートにはお勧めできません大量のデータに対してリーフを追加すると、テーブル内のすべてのレコードを更新できます。 **データがまれに変わる場合は、そのアドバイスを参考にしてください。** – Christian13467

0

これを実装するには、「パス」を含む別のフィールドをレコードに追加する方法があります。一番上のレコードがID = 1であるとします。 ID = 5の子を持っていて、ID = 20の子をもう一度持っていれば、最後のレコードにはパスがあります /1/5/20 トップノードのすべての子ノードを

select * from MyTable where Path like '/1/%' 

(申し訳ありませんが、SQL Serverの構文、私はオラクルの開発者ではないんだ - しかし、概念はまだ適用される)

真ん中のノードの子

select * from MyTable where Path like '/1/5/%' 

にについてのきちんとしたものを取得するにはその解決策は、 "path"フィールドにインデックスを適用できることですこの文は単一の索引スキャンのみを使用して実行され、非常に効率的になります。