如何从数据库中提取和显示分层数据?

时间:2011-12-08 03:16:21

标签: php mysql sql

我有两张桌子。

chapters表格中包含idname列。

chapters_chapter表包含idmaster_idslave_id列。

让我们说chapters表有7条记录:

id     name
1      test01
2      test02
3      test03
4      test04
5      test05
6      test06
7      test07

chapters_chapters表中我有这些记录:

id    master_id    slave_id
1     1            5
2     1            6
3     6            7
4     7            2

鉴于该数据,我如何提取该数据的层次结构,使其看起来像这样?

test01
  test05
  test06
    test07
      test02
test03
test04

2 个答案:

答案 0 :(得分:5)

所以这是一种痛苦,因为我们必须将层次结构存储在数据库中。因此,每个项目可以有多个孩子,每个孩子可以有多个父母

这第二部分意味着我们不能简单地遍历列表一次并完成它。我们可能必须在层次结构中的多个位置插入项目。虽然您可能不会以这种方式实际构建数据,但您所描述的数据库模式支持此方案,因此代码也必须支持它。

这是算法的高级版本:

  1. 查询两个表
  2. 为其子(另一个数组)创建父(数字)的地图(数组)
  3. 创建一组子项(数组)
  4. 创建一个显示单个项目的功能,将其缩进到所需的深度 如果该项目有子项,则此函数将深度增加1,递归调用
  5. 遍历所有非儿童项目(根项目) 为每个项目调用函数,其深度为0(无缩进)。
  6. 这是两个小时的工作。享受:)

    请注意,我将其粘贴在<pre>块内,因此您可能不得不弄乱缩进的方式(输出除两个空格以外的其他内容,混淆div的样式等)。

    <?php
      $con = mysql_connect("localhost", "test_user", "your_password");
      if(!$con)
      {
        die("could not connect to DB: " . mysql_error());
      }
      mysql_select_db("your_db", $con);
    
      // get chapters
      $chapters = array();
    
      $result = mysql_query("SELECT * FROM chapters");
      while($row = mysql_fetch_array($result))
      {
        $id = $row["id"];
        $name = $row["name"];
        $chapters[$id] = $name;
      }
    
      // get chapters_chapters - We'll call it "parent/child" instead of "master/slave"
      $parent_child_map = array();
      $is_child = array();
    
      $result = mysql_query("SELECT master_id, slave_id FROM chapters_chapters");
      while($row = mysql_fetch_array($result))
      {
        $parent_id = $row["master_id"];
        $child_id = $row["slave_id"];
    
        $children = $parent_child_map[$parent_id];
        if($children == null)
        {
          $children = array();
        }
    
        $children[] = $child_id;
        $parent_child_map[$parent_id] = $children;
    
        $is_child[$child_id] = true;
      }
    
      // display item hierarchically
      $display_item_and_children = function($id, $name, $depth)
        use ($chapters, $parent_child_map, &$display_item_and_children)
      {
        echo "<div><pre>";
    
        // indent up to depth
        for($i = 0; $i < $depth; $i++)
        {
          echo "  ";
        }
    
        echo "id: " . $id
          . " name: " . $name
          . "</pre></div>";
    
        // if there are children, display them recursively
        $children = $parent_child_map[$id];
        if($children != null)
        {
          foreach($children as $child_id)
          {
            $child_name = $chapters[$child_id];
            $display_item_and_children($child_id, $child_name, $depth + 1);
          }
        }
      };
    
      // display all top-level items hierarchically
      foreach($chapters as $id => $name)
      {
        // if it is a top-level item, display it
        if($is_child[$id] != true)
        {
          $display_item_and_children($id, $name, 0);
        }
      }
    
      mysql_close($con);
    ?>
    

    这是截图:

    Output of the program

答案 1 :(得分:0)

问题在于您希望解决方案的复杂程度。我将使用以下代码执行此操作。

  • SELECT所有章节
  • SELECT所有* chapters_chapters *
  • 遍历章节以创建数组章节对象
  • 遍历`chapters_chapters *并使用章节对象
  • 创建关系

基本上你正在创建一个link-list