2016-05-16 6 views
0

私は親子関係を達成するために自己の関係を持つtaskという名前のテーブルを持っています。ここで親子関係に基づいて目次インデックスを生成

は、テーブルの構造である:

task (id, name, parent_id) 

任意のタスクはn子供を持つことができます。今

私の見解で、私はこのようなn番目のレベルのネスティングとコンテンツフォーマットのテーブルでタスクを表示する必要があります。

1. Grandfather 

    1.1. Father 

1.2 Mother 

    1.2.1 First Child 

    1.2.1 Second Child 

2. Grandfather's brother 

2.1 Grandfather's brothers son 

3. Grandfather's brother's wife 

明確にするために私は、ネストされた階層レベルを示すために、人間関係のため、これらのタスクを命名しました。私は何

は、私は私のデータベースからすべてのタスクを選択して、このようにそれらを反復処理開始することです:

foreach($tasks as $task) 
{ 
//Get the hierarchy level here and print its index for example 1.1.2 
} 

私は任意のため、1,2,3レベルでそれらを注文する方法がわかりません例えば、インデックスゼロのタスクの実際の位置は3.1.2である。

これはコードレベルで実行できますか? または任意のSQLの提案?

感謝のpostgresで

+0

MySQLかPostgreSQL?関与していない製品にはタグを付けないでください。 – jarlh

+0

Postgresql ...質問に問題があった場合はMySQLを削除しました – Hammad

+0

どのバージョンのpostgresですか? –

答えて

0

あなたは、階層データ構造の全部または一部を読み取るために再帰クエリを書くことができます。

CREATE TABLE task 
(
    id integer NOT NULL DEFAULT, 
    name text, 
    parent_id integer, 
    CONSTRAINT task_pkey PRIMARY KEY (id), 
    CONSTRAINT task_parent_id_fkey FOREIGN KEY (parent_id) 
     REFERENCES public.task (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
); 

insert into task values 
(1, 'grandfather', null), 
(2, 'father', 1), 
(3, 'mother', 1), 
(4, 'first child', 3), 
(5, 'second child', 3), 
(6, 'grandfather''s brother', null), 
(7, 'grandfather''s brother''s son', 6), 
(8, 'grandfather''s brother''s wife', null); 

with recursive relations(relation_id, parent_id, path) as(
    select id as relation_id, null::integer as parent, ARRAY[id]::integer[], from task where parent_id is null 
    union 
    select id, task.parent_id, path || id from relations 
    join task on task.parent_id = relation_id 

) 
select * from relations 
order by path 

出力は次のとおりです。ループのためにあなただけのパス内の各新しい要素と大きさは1つのリセットによりダウンカウンタの番号をインクリメント配列を必要とし、あなたの中に今

relation_id parent_id path 
1      {1} 
2   1   {1,2} 
3   1   {1,3} 
4   3   {1,3,4} 
5   3   {1,3,5} 
6      {6} 
7   6   {6,7} 
8      {8} 

これはおそらく同様にSQLで行うことができる

考慮すべきもう一つのオプションは、あなたの関係を格納する代わりに、PARENT_IDのltreeはを使用しています。それはCTEの必要性を取り除くでしょう

+0

ltreeはツリー操作に非常に便利です。 (例:Grandfather.Father.SecondChildはGrandfather.Father。*クエリに一致する新しいキーです) ここhttp://www.postgresonline.com/journal/archives/173-Using-LTree-to-Represent- and-Query-Hierarchy-and-Tree-Structures.htmlでは、id、parent_idモデルを使用するアプリケーションに基づいてトリガーを追加する方法について説明します。 –

関連する問題