web-dev-qa-db-ja.com

SQLを使用してリレーショナルデータベース内のツリーのようなデータをトラバースする

SQLでツリーデータをトラバースする方法はありますか? Oracleのconnect byについて知っていますが、他のSQL実装でこれを行う別の方法はありますか? connect byを使用する方が、各結果のクエリを実行するループまたは再帰関数を記述するよりも簡単なので、私は尋ねています。

「ツリーデータ」というフレーズに戸惑う人もいるので、さらに説明します。つまり、同じテーブルの別の行の主キーを含むparent_idまたは同様のフィールドを持つテーブルに関しては。

問題は、Oracleデータベースにこの方法で格納されたデータを操作していて、connect byが他のDBMSに実装されていないことを知っていた経験からきています。標準SQLを使用する場合、上に行きたい親ごとに新しいテーブルエイリアスを作成する必要があります。これは簡単に手に負えなくなります。

16
indyK1ng

Celkoの本 は良いリソースです。

私は実際に このメソッド も見つけました。これは「クロージャーテーブル」として知られ、かなりうまく機能します。

再帰的なCTEを許可するデータベース( PostgreSQL 8.4以降 、または SQL Server 2005以降 など)を使用している場合、これらは本当に最適な方法です。 Oracleを使用している場合は、常に由緒ある "connect by" があります。

「ナイーブツリー」スキーマでテーブルのセットを渡され、そのストレージから正しいツリーを抽出する方法を理解する必要があるのは、クリーナーを作成する機会を持つよりもはるかに一般的であるというのが私の経験です。 「クロージャテーブル」の構造。

14
TML

再帰CTEが最も簡単なソリューションになります。 SQL Server 2005および現在のバージョンのPostgreSQLはCTEをサポートしています。 SQL Server 2008以降を使用している場合は、HIERARCHYIDデータ型を使用できます。 HierarchyID:SQL Server 2008でデータ階層をモデル化する で、この良い例を見つけることができます

追加のリソース:

9

SQL Server(2005以降のエディション)では、階層を読み取るために共通テーブル式を使用できます。いくつかの例については、 Microsoft SQL Server 2005-単純な階層のCTEの例 を参照してください。

私は、Joe Celkoによる「SQL for Smartiesのツリーと階層」という、より一般的な主題の本を勧められていますが、私自身はまだこの本を見ていません。

5
David Spillett

標準SQLメソッドは「再帰クエリ」であり、再帰CTEによって提供され、クエリでWITH [ RECURSIVE ]として指定されます。仕様は仕様で指定されていません。再帰的なクエリ構造で利用できるメソッドのみです。最も単純なケースでは、データ構造の実装では、行にIDと親IDのみが必要です。

RDBMS固有のソリューションも多数あります。たとえば、PostgreSQLは再帰CTEをサポートしますが、実装にさまざまな長所と短所を提供する ltree も提供します。

hierarchy タグで検索すると、このサイトの詳細を確認できます。

1
Evan Carroll