0

状況:
ディレクトリのmysqlテーブルがあります。ルートディレクトリのparentIDが0になるまで、各ディレクトリには親ディレクトリ(parentIDとして保存)があります。

例えば:

rowID: 1, name: Dir1,    parentID: 0 (root directory)
rowID: 2, name: Dir2,    parentID: 0 (root directory)
rowID: 3, name: Subdir1, parentID: 1 (lives in "Dir1")
rowID: 4, name: Subdir2, parentID: 1 (lives in "Dir1")
rowID: 5, name: Subdir3, parentID: 3 (lives in "Subdir1", which in turn lives in "Dir1")
rowID: 6, name: Subdir4, parentID: 5 (lives in "Subdir3", which lives in "Subdir1", which lives in "Dir1")

したがって、ここには3つのディレクトリの深さの構造があります。

任意のディレクトリをその親に結合し、最後に結合されたディレクトリのparentIDが0になるまで(つまり、ルートディレクトリが見つかるまで)ステートメントを作成する必要があります。どのディレクトリでも、ブレッドクラムを親に戻すことができるかのように考えることができます。

これにはMySQLのループが必要になる可能性があると思いますが、私の人生では、Webの例を機能させることはできません。ある種の構文エラーが含まれているように見えるため、いくつかの例を実行することさえできません。誰かが私が始めるのを手伝ってもらえますか?

これを実行するために最も簡単で最高のパフォーマンスを提供する任意の結果形式を受け入れることができます。正しい順序の行番号の単純な配列(たとえば、5、3、1、0、ID 0に到達するためのステップを示す)、またはこれを達成する行の順序付きリストである完全なテーブル(最良)のいずれか、例えば

rowID: 5, name: Subdir3, parentID: 2;
rowID: 3, name: Subdir1, parentID: 1;
rowId: 1, name: Dir1,    parentID: 0;

よろしくお願いします!

4

2 に答える 2

0

間違った検索用語を使用したため、適切な Web 例が見つからなかった可能性があります。説明されている問題は、オラクルの CONNECT BY PRIOR ステートメントに完全に適合し、このステートメントに相当する mysql をグーグルで検索すると、http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/が非常に高速であることがわかります。

このようなことを書くのはそれほど簡単ではないので(そしてここでレイプするmysql-dbはありません)、与えられた良い例を一目見てください(http://explainextended.com/を介してデプロイされた関数なしでそれを行うこともできます) 2009/07/20/階層データの mysql の親と子の 1 つのクエリ/ .

それでもわからない場合は、家でお手伝いできるかもしれません。

于 2012-08-27T12:12:00.800 に答える
0

さて、説明したのと同様の構造を持つ単純なデータベースを実際にデプロイする時間を見つけました。

表は次のとおりです。

CREATE TABLE `t_hierarchy` (
    `rowID` INT(11) NULL DEFAULT NULL,
    `name` VARCHAR(50) NULL DEFAULT NULL COLLATE 'latin1_general_ci',
    `parentID` INT(11) NULL DEFAULT NULL
);

基本的に、上記とまったく同じものを挿入しましたが、ルート/親なしに0の代わりにNULL値を使用しました

私が行ったことは、http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/の非常に不可解な例です。列名を私のものに合うように修正しました。

これは再帰的な階層を生成するだけなので、例にばかげた結合を追加しました ( ad.rowID = qi.id ):

 SELECT  qi.id, qi.parent, ad.rowId, ad.name, level
FROM    (
        SELECT  @r AS id,
                (
                SELECT  @r := parentID
                FROM    t_hierarchy
                WHERE   rowID = id
                ) AS parent,
                @l := @l + 1 AS level
        FROM    (
                SELECT  @r := 5, -- change this 5 to the directory ID you want to resolve
                        @l := 0,
                        @cl := 0
                ) vars,
                t_hierarchy h
        WHERE   @r <> 0
        ORDER BY
                level DESC
        ) qi, t_hierarchy ad
        WHERE ad.rowID = qi.id

そして、これは次の(望ましい)出力を生成します:

id 親 rowId 名前 レベル

1 ヌル 1 方向 1 3

3 1 3 サブディレクトリ 1 2

5 3 5 サブディレクトリ 3 1

レベルは、これに到達するために解決する必要があった「深さ」を示すヘルパー列です。@r := の横にある "5" を、反復したいディレクトリ ID に変更するだけです。

方向を (上から下に) 切り替えたい場合は、単純にレベル列で並べ替えます ([...] WHERE ad.rowID = qi.id ORDER BY level ASC )

これがお役に立てば幸いです。

編集: qi.id と ad.rowID は重複しています。そのうちの 1 つを削除してください ;-) ... いまいましい私はその階層的なものが嫌いです

于 2012-08-31T15:25:42.190 に答える