2016-08-10 1 views
0

私はこのようなデータのセットがあります。私はなるだろうどのように

ID  NAME  OLDEST 
---- ------  ------- 
1  Obj #1  NULL 
2  Obj #2  1 
3  Obj #3  1 
4  Obj #4  1 
5  Obj #5  1 
6  Obj #6  NULL 
7  Obj #7  6 

:私は彼らの最古の祖先でそれらを取得したいのであれば、私はこのような結果を得るだろう

ID  NAME  PARENT 
---- ------  ------- 
1  Obj #1  NULL 
2  Obj #2  1 
3  Obj #3  4 
4  Obj #4  2 
5  Obj #5  3 
6  Obj #6  NULL 
7  Obj #7  6 

をこれを行うためのクエリ?

+1

あなたが使用することができますhttp://stackoverflow.com/questions/20215744/how-to-create-a-mysql-hierarchical-re筆記体のクエリーを作成し、最も古い祖先を得るためにこれを少し変換します。 –

+0

あなたは本当にMySQLの単一のクエリでそれを行うことはできません。 – Uueerdo

+0

@Uueerdo私はほとんどあなたができることを確信しています。しかし、現時点でそれを証明する時間を見つけることはできません。 –

答えて

0

ので、時間の不足のため、私は最高のものではなく、使用してのロジックで動作している(1つのソリューションをご紹介しますと、自己結合を繰り返し、あなたの階層の上限を知っている場合にのみ、木)。 5の深階層内の指定された最古の祖先を見つけるために

create table tbl(id int, parent int); 
insert into tbl values (1,null),(2,1),(3,4),(4,2),(5,3),(6,null),(7,6); 

クエリ:ここ

は( "名前" 欄せずに、あなたのような)作業SQL Fiddle.

テストデータ生成ですツリー:

select 
    t1.id, coalesce(t5.id, t4.id, t3.id, t2.id) as oldest 
from tbl t1 
left join tbl t2 on t1.parent = t2.id 
left join tbl t3 on t2.parent = t3.id 
left join tbl t4 on t3.parent = t4.id 
left join tbl t5 on t4.parent = t5.id 
order by 1; 
+0

くそー、それに私を打つ。 – Uueerdo

+0

残念ながら、私はどれくらい深く行くことができるのか分かりません。それは無制限です。 –

+0

明日、別の解決策を提示することがあります。 –

0

いくつかのコメントは、 "ネストされたse Joe CelkoのSQLブックで普及している「t」モデルです。しかし、私は、データモデルを維持することが困難であることがわかり、それがデータを変更するために複雑です。

私はこの好評スタックオーバーフローの答えに記載されている「閉鎖テーブル」と呼ぶデザインを好む:What is the most efficient/elegant way to parse a flat table into a tree?

あなたのクエリは次のようになります。

SELECT c.ID, c.NAME, a.ID AS OLDEST 
FROM MyTable AS t 
JOIN ClosureTable AS c ON t.ID = c.descendant 
JOIN MyTable AS a ON a.ID = c.ancestor 
WHERE a.PARENT IS NULL; 

私もこのモデルをカバー私のプレゼンテーションModels for Hierarchical Data中(および他のソリューション)。

は、ここに私の提供するこのプレゼンテーションのビデオ録画です:Models for Hierarchical Data

私はまた私の本、SQL Antipatterns: Avoiding the Pitfalls of Database Programmingで階層データに関する章を書きました。


あなたが現在それを保存としてあなたのデータで動作するクエリが必要な場合は、ここでQuassnoiの巧妙なソリューションを参照してください。https://stackoverflow.com/a/8111762/20860

しかし、それは、MySQLの文書化されていない動作に依存しているので確かに、それは安定した解決策ではありません。私はそれから遠ざかるだろう。


あなたがコードやテーブル構造を変更することはできません、とあなたは今日、それを必要とする場合、あなたはそれが一定のレベルに制限されているにもかかわらず、カミルG.からの回答と一緒に行く必要があるとしています階層の深さの他に解決策はありません、申し訳ありません。

+0

残念ながら、私はそのような新しいテーブルを作成することはできません。私はそれを最新の状態に保つために多くのコードを変更しなければならないでしょう。それは起こることはありません –

0

は、私は通常MySQLのでこれを設計し直すので、テーブルは次のようになります。

id  name 
10  Obj#1 
1010 Obj#2 -- parent = 10 
101020 Obj#6 -- parent = 1010 -- grandparent = 10 ... etc 

そして、私はあなたの現在の設計のための怠惰なSQLがあります(ネストされたの6つのレベルを、あなたがあれば、よりを追加することができますあなたはより深いネスティング)が

SELECT a.id, a.NAME, 
    ifnull(p6.PARENT, ifnull(p5.PARENT, ifnull(p4.PARENT, ifnull(p3.PARENT, ifnull(p2.PARENT, ifnull(p.PARENT, p.id)))))) AS PARENT 
FROM 0_a2 AS a 
LEFT JOIN 0_a2 AS p ON a.PARENT = p.id 
LEFT JOIN 0_a2 AS p2 ON p.PARENT = p2.id 
LEFT JOIN 0_a2 AS p3 ON p2.PARENT = p3.id 
LEFT JOIN 0_a2 AS p4 ON p3.PARENT = p4.id 
LEFT JOIN 0_a2 AS p5 ON p4.PARENT = p5.id 
LEFT JOIN 0_a2 AS p6 ON p5.PARENT = p6.id 
ORDER BY a.id 

enter image description here

+0

オブジェクトがレベル20の階層の変更をそれがすべての方法でアップしていると言うことができる場合、 –

+1

@ KamilG。はい、私のデザインは、クエリーのために素早く、構造の整ったデザインに適しています。主に製品カテゴリに使用されますが、通常は最大3つのレベルが維持しやすいです。例えば家系には適していない – SIDU