2009-08-14 4 views
2

の比較の間に、次の表:行方向を考えると、単一のSQL文

CREATE TABLE tree (
    id serial NOT NULL, 
    name character varying NOT NULL, 
    type integer, 
    lft integer NOT NULL, 
    rgt integer NOT NULL) 

CREATE TABLE item (
    id serial NOT NULL, 
    name character varying NOT NULL, 
    tree_id integer 
    CONSTRAINT fk_tree FOREIGN KEY (tree_id) REFERENCES tree (id)) 

列修正先行順ツリートラバーサル(MPTT)アルゴリズムを使用して移入され、テーブルtreelftrgt

タイプ= xのツリーノードに接続されているすべてのアイテムをすべて取得して、クエリのすべての子孫を取得することはできますか?

SELECT lft, rgt FROM tree WHERE type = x; 
/* assume it returns two rows: ((10, 20), (27, 30)) */ 

SELECT item.id, item.name FROM item JOIN tree ON (tree_id = tree.id) 
WHERE ((lft >= 10 AND rgt <= 20) OR (lft >= 27 AND rgt <= 30); 

ポイントは(それが重要ならば、PostgreSQLデータベースに)私は、単一のSQLステートメントを実行することができるということです。

通常、私はこのような二つの別々のクエリでそれを行うだろう。あなたは何らかのサブクエリでこれを行うことができますか?

ありがとうございます。

答えて

2
SELECT item.* 
FROM tree tm 
JOIN tree tc 
ON  tc.lft >= tm.lft 
     AND tc.rgt <= tm.rgt 
JOIN item 
ON  item.tree_id = tc.id 
WHERE tm.type = x 

管理が簡単な親子モデルを検討してください。

PostgreSQL 8.3、以下にそれを実装する方法について私のブログでこれらの記事を参照してください。

、およびPostgreSQL 8.4中:

+0

item.idとtree.idは、lftとrgtとして格納されたMPTT値とは関係ありません。ツリーのテーブル項目からの結合は、外部キーによってのみ実行できます。 – Haes

+0

'@ Haes':申し訳ありませんが、それを取得していません。ポストアップデートを参照してください。 – Quassnoi

+0

np、ご協力いただきありがとうございます。ツリーモデルは、読み取りパフォーマンスのために最適化する必要があります。つまり、MPTTモデルが選択された理由です。あなたが更新された答えはまさに私が探していたものです。 – Haes

0

特定のデータ構造にクエリを書く際に問題がある場合は、他のデータ構造の使用を検討するべきでしょうか?ネストされたセット(あなたがここに示したもの)はクールに見えますが、クエリを書くときには大きな苦痛です。

おそらくthis(公開:私のブログの投稿)のようなものを使うことができます。

関連する問題