MySQL SELECT树父ID

时间:2011-04-16 17:45:51

标签: php mysql sorting

如何对SELECT语句的记录进行排序,使它们代表一个有效的树?

我的所有尝试都显示子节点嵌套在错误的父节点下。实现这种排序的最可靠方法是什么?

数据

ID      Parent ID      Title
--------------------------------------------
0       NULL           Root
1       0              Node A
2       0              Node B
3       1              Sub-Node C
4       1              Sub-Node D
5       3              Sub-Node E

输出

ID      Parent ID      Title
--------------------------------------------
0       NULL           Root
1       0              Node A
3       1              Sub-Node C
5       3              Sub-Node E
4       1              Sub-Node D
2       0              Node B

数据可视化

Root
    Node A
        Sub-Node C
            Sub-Node E
        Sub-Node D
    Node B

5 个答案:

答案 0 :(得分:13)

您可以使用嵌套集。看看这篇文章:

Managing Hierarchical Data in MySQL

作者描述了在SQL中构建层次结构的几种不同方法,以及示例查询。关于这个主题,这是一个很好的阅读!

答案 1 :(得分:5)

根据@Blindy的建议,我已经用PHP实现了这种方式。以下两个函数似乎相对容易解决了这个问题。

protected function _sort_helper(&$input, &$output, $parent_id) {
    foreach ($input as $key => $item)
        if ($item->parent_id == $parent_id) {
            $output[] = $item;
            unset($input[$key]);

            // Sort nested!!
            $this->_sort_helper(&$input, &$output, $item->id);
        }
}

protected function sort_items_into_tree($items) {
    $tree = array();
    $this->_sort_helper(&$items, &$tree, null);
    return $tree;
}

我很想知道是否有更简单的方法,但这确实有用。

答案 2 :(得分:4)

MySQL不支持递归查询

您需要自动加入表格,因为最大层次结构级别是多次,但是以这种方式为每个层次结构级别获取一行仍然非常难看。

请参阅这些帖子以获取一些想法和示例:

Category Hierarchy (PHP/MySQL)

how can we write mysql query where parent id have a child id and next time child id is a parent id how can i do?

答案 3 :(得分:0)

我刚刚完成了这个递归函数,并认为这是一个关于问题的优雅方式。这是我做了一个基本的SELECT mysql查询后所做的事情:

function orderChildren($data){
    $tree = array();
    foreach($data as $value){
        if($value['parent_id'] == null){  // Values without parents
            $tree[$value['id']] = $this->goodParenting($value, $data);
        }
    }
    return $tree;
}

private function goodParenting($parent, $childPool){
    foreach($childPool as $child){
        if($parent['id'] == $child['parent_id']){
            $parent['children'][$child['id']] = $this->goodParenting($child, $childPool);
        }
    }
    return $parent;
}

答案 4 :(得分:0)

这是另一种执行PHP功能的方法。

function buildTree() {
  $data = array();
  $pointers = array();

  $sql = "SELECT ID,PARENT,TITLE FROM TREE ORDER BY TITLE ASC";
  $res = $this->db->query($sql);

  while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
    if(!isset($pointers[$row['ID']])) {
      $pointers[$row['ID']] = $row;
    }

    if(!empty($row['PARENT'])) {
      if(!isset($pointers[$row['PARENT']])) {
        $pointers[$row['PARENT']] = $row;
      }
      $pointers[$row['PARENT']][$row['ID']] =  &$pointers[$row['ID']];
    } else {
      $data[$row['ID']] = &$pointers[$row['ID']]; // This is our top level
    }
  }

  unset($pointers);
  return $data;
}