深さに制限はありません。
構造化されたブランチまたはツリー全体を取得するにはどうすればよいですか?
定義はここからです:MySQLでの階層データの管理
それがあなたが求めているものかどうかはわかりませんが、ツリー全体、パスごとに 1 行、各パスを文字列として取得できることに注意してください。http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/からの単一パス」の例
SELECT
GROUP_CONCAT(parent.name ORDER BY parent.lft ASC SEPARATOR '|')
FROM nested_category AS node
CROSS JOIN nested_category AS parent
WHERE
node.lft BETWEEN parent.lft AND parent.rgt
GROUP by node.id
ORDER BY node.lft;
これにより、ツリー内のすべてのノードのパスが出力されます。
nested_category AS node CROSS JOIN nested_category AS parent
と同等であることに注意してくださいnested_category AS node, nested_category AS parent
。
これは、文字列'|'
を区切り文字として指定します。これをパス要素の配列に分解したい場合、データにない文字列があることがわかっている場合は、代わりにそれを指定できます。
私は同様のアプローチを使用しますが、まったく同じではありません。これは、子の親への参照も保持します。これにより、データからツリー構造を簡単に構築できます。これが役立つ場合は、PHP でデータをツリーに抽出するためのコードを投稿できます。
@Marc、説明されているデータ構造は、必ずしもセット操作を行うためのものではありません。構造の操作が簡単になるだけです。データのツリー全体を取得する必要があり、各レコードに親レコードへのポインターが格納されているだけの場合は、データベースを再帰的にクエリして、データのツリー全体を取得する必要があります。そこで説明されているアプローチを使用すると、1 つのクエリでセット全体を抽出できます。
編集:これは、子を維持する場合にツリー構造を構築するコードです->親参照とlft/rightのもの。ツリーの単一レベルの直接の子孫のみを取得したい場合は、この方法の方が実際には高速であるため、私はこれを行うことを好みます。
本質を示すためにそれを取り除いてみたので、タイプミスなどがあるかもしれませんが、アイデアを得る必要があります. 重要な部分は
とにかく、ここにコードがあります -
<?php
$children = mysql_query('SELECT * FROM nested_category ORDER BY lft ASC');
/* Get the first child; because the query was ordered by lft ASC, this is
the "root" of the tree */
$child = mysql_fetch_object($children);
$root = new StdClass;
$root->id = $child->folderID;
$root->children = array();
/* Store a reference to the object by the id, so that children can add
themselves to it when we come across them */
$objects = array($root->id => $root);
/* Build a tree structure */
while ($child = mysql_fetch_object($children)) {
/* Create a new wrapper for the data */
$obj = new StdClass;
$obj->id = $child->id;
$obj->children = array();
/* Append the child to the parent children */
$parent = $objects[$child->parent];
$parent->children[] = $obj;
$objects[$obj->id] = $obj;
}
mysql 側のデータ構造が多少変わっている場合でも、データは通常のクエリ メソッドを使用して取得されます。適切な select ステートメントを発行し、結果をループして、PHP 配列に詰め込みます。MySQL よりも PHP で集合操作を行う方がはるかに難しいため、なぜそうしたいのかはわかりません。
php..を使用して再帰を使わずにツリー構造を操作できる方法についてお知らせします。標準 php ライブラリ (SPL) についてはよく知られていると思います。質問にはイテレータを使用できます。
http://www.php.net/~helly/php/ext/spl/
SPL のドキュメントへのリンクは次のとおりです。上記のMysqlリンクの例のいくつかのソリューションを次に示します:-テーブルから配列を取得するだけで、配列を操作して好みに合わせて表示できます
For :- 隣接リスト モデル
すべての子を含むすべての結果を表示する「RecursiveIteratorIterator」を使用できます。
子供だけ見せたいなら。「ParentIterator」を使用できます
あなたのリンクを見ると、Left Joinsでそれを行います。完全なツリーの取得の例を見てください。
SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
WHERE t1.name = 'ELECTRONICS';
含める階層レベルごとに LEFT JOIN が必要です。結果は、php によって任意の望ましいデータ構造に解析できます。NULL
結果を無視するだけです。
| ELECTRONICS | TELEVISIONS | TUBE | NULL |
| ELECTRONICS | TELEVISIONS | LCD | NULL |
| ELECTRONICS | TELEVISIONS | PLASMA | NULL |
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH |
| ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS | NULL |
| ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL |
構造が深い場合、多くのテーブルを結合する必要がある場合、MySQL Join の実行に長い時間がかかるため、これは悪い方法です。
あなたの質問を誤解していないことを願っています。