2016-04-06 7 views
0

私はいくつかの類似点を見つけましたが、必要なものは何も見つかりませんでした。MySQL:トップ/究極の親を見つける

ID | PARENT 
1 | NULL 
2 | 5 
3 | 6 
4 | 6 
5 | NULL 
6 | 9 
7 | NULL 
8 | 7 
9 | 8 
10 | NULL 

次のような表があり、MySQLを使用して最上位の親を見つける必要があります。私がこれで抱えている問題は、上位階層に達するために階層構造の段階で最大20個になる可能性があることです。私はMySQLで十分理解していないと思っています。

ありがとうございます!

+0

親としてNULLを持つものはどうですか? –

+0

NULLの親は、それが最上位の親であることを意味します。通常、これは再帰的な問合せ(共通の表式を使用するかoracleで事前に接続する)で行われますが、私のSQLではこれがありません。 http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/はそれを行う方法を提供しますが、私はそれを自分で使っていません。 http://stackoverflow.com/questions/3137674/mysql-best-method-to-handle-this-hierarchical-dataにもメソッドがあります。 – xQbert

+0

無限または不確実な深さのツリーに関しては、いわゆるエッジまたは隣接リストはそれほど大きくありません。オプションには、必要に応じてテーブルを頻繁に結合する、再帰を処理するsprocを作成する、アプリケーションレベルのコードで再帰を処理する、または代替モデル(ネストされたセットなど)に切り替える方法があります。 – Strawberry

答えて

0

私からの回答です。それはいいですが、それは動作します。 MariaDBここ= 8

SELECT path, sid 
FROM (
    SELECT *, @sid AS sid, @path := CONCAT(@path,' -> ', @sid) AS path, 
    (SELECT (@sid:=parent) FROM mytab WHERE id = @sid) AS parent 
    FROM seq_1_to_99 
    CROSS JOIN (SELECT @sid := 8 , @path :[email protected]) AS parameter 
    HAVING parent = @sid 
) AS result 
ORDER BY seq DESC 
LIMIT 1; 
@sidを設定する必要があります最初のクエリは、シーケンスエンジンとMariaDBのためのものであり、長くは "通常" のMySQL

開始パラメータ(ID)フロンであります

MySQLの

SELECT path, sid FROM (
SELECT *, @sid AS sid, 
@path := CONCAT(@path,' -> ', @sid) AS PATH, 
(SELECT (@sid:=parent) FROM mytab WHERE id = @sid) AS parent 

FROM (
    SELECT * 
    FROM (
    SELECT d2.a*10+d1.a AS nr 
    FROM (
     SELECT 0 a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL 
     SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL 
     SELECT 8 UNION ALL SELECT 9) AS d1 
     CROSS JOIN (
     SELECT 0 a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 ) AS d2 
) AS counter 
    ORDER BY counter.nr 
) AS result 
CROSS JOIN (SELECT @sid := 8 , @path :[email protected]) AS parameter 
HAVING parent = @sid 
) AS p 
ORDER BY nr DESC 
LIMIT 1; 

サンプル

MariaDB []> select * from mytab; 
+----+--------+ 
| id | parent | 
+----+--------+ 
| 1 | NULL | 
| 2 |  3 | 
| 3 | NULL | 
| 4 | NULL | 
| 5 |  4 | 
| 6 |  5 | 
| 7 |  8 | 
| 8 |  6 | 
+----+--------+ 
8 rows in set (0.00 sec) 

MariaDB []> SELECT path, sid 
    -> FROM (
    -> SELECT *, @sid AS sid, @path := CONCAT(@path,' -> ', @sid) AS path, 
    -> (SELECT (@sid:=parent) FROM mytab WHERE id = @sid) AS parent 
    -> FROM seq_1_to_99 
    -> CROSS JOIN (SELECT @sid := 8 , @path :[email protected]) AS parameter 
    -> HAVING parent = @sid 
    ->) AS result 
    -> ORDER BY seq DESC 
    -> LIMIT 1; 
+-------------+------+ 
| path  | sid | 
+-------------+------+ 
| 8 -> 6 -> 4 | 4 | 
+-------------+------+ 
1 row in set (0.01 sec) 

MariaDB []> SELECT path, sid FROM (
    -> SELECT *, @sid AS sid, 
    -> @path := CONCAT(@path,' -> ', @sid) AS PATH, 
    -> (SELECT (@sid:=parent) FROM mytab WHERE id = @sid) AS parent 
    -> 
    -> FROM (
    -> SELECT * 
    -> FROM (
    ->  SELECT d2.a*10+d1.a AS nr 
    ->  FROM (
    ->   SELECT 0 a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL 
    ->   SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL 
    ->   SELECT 8 UNION ALL SELECT 9) AS d1 
    ->  CROSS JOIN (
    ->   SELECT 0 a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 ) AS d2 
    -> ) AS counter 
    -> ORDER BY counter.nr 
    ->) AS result 
    -> CROSS JOIN (SELECT @sid := 8 , @path :[email protected]) AS parameter 
    -> HAVING parent = @sid 
    ->) AS p 
    -> ORDER BY nr DESC 
    -> LIMIT 1; 
+-------------+------+ 
| path  | sid | 
+-------------+------+ 
| 8 -> 6 -> 4 | 4 | 
+-------------+------+ 
1 row in set (0.01 sec) 

MariaDB []> 

私はそれはあなたに少しのに役立ちます願っています。

関連する問題