6

私が求めていることが可能かどうかはわかりませんが、これが私の状況です。次のような構造のテーブルがあります。

+--------------------------------------------------+
|   id   |   parent_id   |   name   |   category   | ....
+--------------------------------------------------+
|    0   |       -1      |   item0  |      1       |
|    1   |        0      |   item1  |      1       |
|    2   |        0      |   item2  |      1       |
|    3   |        2      |   item3  |      1       | 
|    4   |        2      |   item4  |      1       | 
|    5   |       -1      |   item5  |      1       | 
+--------------------------------------------------+

-1 の parent_id は、親のない「ベース」アイテムであることを意味します。各項目には、より多くの情報の列があります。次のようにネストされたカテゴリ内のすべてのアイテムを何らかの方法で出力する必要があります。

item0 => item1    
      => item2
            => item3
            => item4  
item5  

それが理にかなっているのかどうかはわかりませんが、うまくいけばそうなるでしょう!

これを行う唯一の方法は、クエリを作成してすべての「ベース」アイテムを取得し (parent_id = -1 の行をクエリする)、結果のすべての行を反復処理し、parent_id が現在と等しい行をクエリすることです。行の ID を取得し、ベース アイテムの子がなくなるまでこのプロセスを繰り返します。

より良い方法はありますか?

ありがとう!!

4

3 に答える 3

10

純粋な SQL では不可能です。

SQL は、ツリー (階層データ) ではなくリレーショナル データを操作することを目的としています。

SQL スキーマでツリーを表すことはできますが、意図したとおりにツリーを作成することはできません。

唯一の方法は、格納しているレベルと同じ数の結合を作成して、使用可能な結果を​​取得することです。

現在のスキーマは複数のレベルをサポートしている可能性がありますが、複数のレベルを管理することは非常に困難です。

ネストされたセット モデルまたはmysql での階層データの管理に興味があるかもしれません

Doctrine 2 で動作する、このようなネストされたセットの実装がいくつかあります。

于 2012-06-19T22:34:27.830 に答える
1

これは純粋な SQL では不可能であり、最も多くの批判を生み出すリレーショナル モデルの側面の 1 つです。

この投稿のリンクを読むことをお勧めします: SQL "tree-like" query - mostparent group

また、アプリケーションがこれに依存しすぎている場合は、MongoDB ( www.mongodb.org ) など、この種のデータをより適切に表現できる非リレーショナル データベースを検討することをお勧めします。

于 2012-06-19T22:38:57.107 に答える
1

あなたの質問をよく理解できたと思います(ここではかなり遅く、バーから来たばかりです)。そうでない場合は、修正して回答を書き直します。

与えられたシナリオから、別の親テーブルがあると思いますね。

その属性が id と name であると想像してみましょう。Children テーブルはあなたが指定したものです (不要な属性はありません)。

mysql> insert into parent(name) values ('petr'),('tomas'),('richard');


mysql> insert into children(name,parent_id) values('michal',1),('tomas',1),('michal');


mysql> select parent.id,parent.name,children.name from parent left join children on parent.id = children.parent_id;

+----+---------+--------+
| id | name    | name   |
+----+---------+--------+
|  1 | petr    | michal |
|  1 | petr    | tomas  |
|  2 | tomas   | NULL   |
|  3 | richard | michal |
+----+---------+--------+

これを複数回行うには (親が子を取得し、子を取得した子など)、複数の結合を使用してそれを実現できます。

mysql> select parent.id,parent.name as Parent,children.name as Child,children2.name as Child2 from parent left join children on parent.id = children.parent_id left join children2 on children.id = children2.parent_id;
+----+---------+--------+--------+
| id | Parent  | Child  | Child2 |
+----+---------+--------+--------+
|  1 | petr    | michal | NULL   |
|  1 | petr    | tomas  | dan    |
|  1 | petr    | tomas  | pavel  |
|  2 | tomas   | NULL   | NULL   |
|  3 | richard | michal | michal |
+----+---------+--------+--------+

あなたが尋ねたことに私が答えなかった場合、またはさらに説明が必要な場合は、私に知らせてください;]

よろしく、

ルレ

于 2012-06-19T22:53:19.127 に答える