0

次のような目次の表があります。

  • ID
  • 親_ID
  • 表示順

したがって、各行は章の見出しですが、章内、章内に章が存在する場合があります。したがって、上記の表により、これらの関係を維持できます。

チャプターに親がない場合、つまり他のチャプターのサブチャプターでない場合、Parent_ID は「Null」です。チャプタに親がある場合、Parent_ID は親チャプタの ID に設定されます。

チャプター内に複数のサブチャプターが存在する可能性があるため、これらのサブチャプターの順序は Display_Order 列で管理されます。1 が最初など。

テーブル全体を選択し、上記の結果を生成できるきちんとした SQL クエリを提案できる人はいますか? 基本的に、章の実際の階層を反映した結果セットを探しています。以下のASCII TOC!

Chapter
-- Chapter
---- Chapter
---- Chapter
---- Chapter
-- Chapter
---- Chapter
---- Chapter
Chapter
Chapter

4

1 に答える 1

0

SQL クエリだけで行うことはできません (少なくとも MySQL では)。SQL と PHP を使用したアプローチの 1 つは、次のとおりです。

SELECT id, IFNULL(parent_id, 0) AS parentid, chapter FROM toc ORDER BY parentid, display_order

次に、この行セットを次のように配列 $a に読み取ります。

while ($row = mysql_fetch_array($result)) {
    $a[$row['id']]['name'] = $row['chapter'];
    $a[$row['parentid']]['children'][] = $row['id'];
}

最初のインデックスが 0 の架空の要素を作成します。

特定のレベルのインデントを出力するための小さなサンプル関数 (インデントを生成する代わりに CSS をパディングまたはその他の方法で使用できます):

function printIndent($level = 0) {
    for ($j = 0; $j <= $level; $j++) echo '&nbsp';
}

次に、ツリーを出力する再帰関数 printTree を作成します。

function printTree($key = 0, $level = 0) {
    if ($key > 0) {
         printIndent($level);
         echo $a[$key]['name'];
    }
    if (count($a[$key]['children'])
        foreach ($a[$key]['children'] as $child)
             printTree($child, $level + 1);
}

そして、あなたはそれを一度呼び出す:

printTree();

これです。配列の初期化をスキップし、このサンプル コードを実行しなかったことに注意してください。したがって、構文エラーがある可能性がありますが、原則はこれです。

このアプローチの欠点は、アイテムの数が非常に多い場合、最初にすべてを一度に大きな配列に読み取るため、最も効果的ではないことです。ただし、アイテムの数が少ない場合は、これが適切なソリューションです。

于 2011-10-19T17:16:55.553 に答える