Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何从同一表中的父行获取所有子行?_Sql_Mysql - Fatal编程技术网

Sql 如何从同一表中的父行获取所有子行?

Sql 如何从同一表中的父行获取所有子行?,sql,mysql,Sql,Mysql,假设我有一个名为my_table的表,看起来像这样: id | name | parent_id 1 | Row 1 | NULL 2 | Row 2 | NULL 3 | Row 3 | 1 4 | Row 4 | 1 5 | Row

假设我有一个名为my_table的表,看起来像这样:

id      |  name                    | parent_id
1       |  Row 1                   | NULL
2       |  Row 2                   | NULL
3       |  Row 3                   | 1
4       |  Row 4                   | 1
5       |  Row 5                   | NULL
6       |  Row 6                   | NULL
7       |  Row 7                   | 8
8       |  Row 8                   | NULL
9       |  Row 9                   | 4
10      |  Row 10                  | 4
Array
(
    [0] => Array
        (
            [name] => Row 1
            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => Row 3
                            [children] => 
                        )

                    [1] => Array
                        (
                            [name] => Row 4
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [name] => Row 9
                                            [children] => 
                                        )

                                    [1] => Array
                                        (
                                            [name] => Row 10
                                            [children] => 
                                        )

                                )

                        )

                )

        )

    [1] => Array
        (
            [name] => Row 2
            [children] => 
        )

    [2] => Array
        (
            [name] => Row 5
            [children] => 
        )

    [3] => Array
        (
            [name] => Row 6
            [children] => 
        )

    [4] => Array
        (
            [name] => Row 8
            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => Row 7
                            [children] => 
                        )

                )

        )

)
基本上,我希望PHP中的最终数组如下所示:

id      |  name                    | parent_id
1       |  Row 1                   | NULL
2       |  Row 2                   | NULL
3       |  Row 3                   | 1
4       |  Row 4                   | 1
5       |  Row 5                   | NULL
6       |  Row 6                   | NULL
7       |  Row 7                   | 8
8       |  Row 8                   | NULL
9       |  Row 9                   | 4
10      |  Row 10                  | 4
Array
(
    [0] => Array
        (
            [name] => Row 1
            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => Row 3
                            [children] => 
                        )

                    [1] => Array
                        (
                            [name] => Row 4
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [name] => Row 9
                                            [children] => 
                                        )

                                    [1] => Array
                                        (
                                            [name] => Row 10
                                            [children] => 
                                        )

                                )

                        )

                )

        )

    [1] => Array
        (
            [name] => Row 2
            [children] => 
        )

    [2] => Array
        (
            [name] => Row 5
            [children] => 
        )

    [3] => Array
        (
            [name] => Row 6
            [children] => 
        )

    [4] => Array
        (
            [name] => Row 8
            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => Row 7
                            [children] => 
                        )

                )

        )

)
因此,我希望它获取parent_id为null的所有行,然后递归地查找所有嵌套的子行

下面是我遇到麻烦的部分:

如何通过对数据库的一次调用来实现这一点


我相信我可以用一个简单的select语句来实现,然后让PHP使数组看起来像这样,但我希望这可以通过某种奇特的db连接或类似的方式来实现。

AFAIK这是不可能的。除非您编写一些存储过程来完成这项工作。

我不知道如何从单个数据库调用中获取这样的数组。mysql查询返回一个类似于表的数据集,它总是基于列的。因此,答案是你不能

但是,可以进行非常智能的基于树的查询。关于这一点,可以找到一本非常有趣的书

在mysql以外的其他系统上,可以实现您想要的


但仍然没有现成的数组。

我不知道MySQL,但在SQL Server(我相信这是ANSI-SQL)中,这是通过CTE(公共表表达式)完成的,它采用以下形式:

WITH MyCTE
(
  -- Non-recursive anchor query
  UNION ALL
  -- Recursive portion that typically JOINs MyCTE to some other table  
)
SELECT * FROM MyCTE;

MySQL中没有递归查询,但有嵌套集的思维方式。完整的参考资料就在这里:

在MySQL中,您可以创建存储过程,它将返回您需要的内容。您可以查看MSSQL的简单示例。但MySQL也很容易实现

这里的问题是,Id并不是按照遍历树的顺序存储的。如果您通过构建树一次来解决此问题,然后按照遍历节点的顺序将所有节点复制回另一个分配Id的表中,下次您将能够通过简单扫描select语句的前向结果来填充树,如

从my_表中选择*按Id排序


若树经常更改,此解决方案将不起作用,因为必须重新生成表。这可以通过将Id最初增加一个大的数字(比如1000)来解决,这样就不必每次都重新编号,因为您可以从间隙中分配新的节点Id。如果树的高度很小,使用分数作为键也可以很好地工作。

最简单的方法就是用PHP来实现。我必须在Symfony中做一些类似的事情,但是它应该很容易阅读和适应。从表行中的数组开始

  public function executeGetTree(sfWebRequest $request)
  {
    $rows = Doctrine_Core::getTable('TreeNode')->findAll();
    $treeNodes = $rows->toArray();

    //set up new array to store children for each parent node
    $nodesContainer = array();
    foreach ($treeNodes as $node){
        $parentId = $node['parent_id'];
        //if node has no parent, it is a root node
        $nodesContainer[isset($parentId)? $parentId : 'root'][] = $node;
    }

    $tree = array();
    //recursively get descendents for each root node
    foreach($nodesContainer['root'] as $rootNode)
    {
      $tree[] = $this->getChildren($nodesContainer, array($rootNode));
    }

    print_r($tree);

    return sfView::NONE;
  }

  private function getChildren(&$container, $parentNode){
      $children = array();
      foreach ($parentNode as $node){
          if(isset($container[$node['id']])){
            $node['children'] = $this->getChildren($container, $container[$node['id']]);
          }
          $children[] = $node;
      } 
      return $children;
  }  
我希望这可以通过加入某种奇特的db或类似的方式来实现

你应该考虑听起来是多么的不可能。 只考虑树中的一个分支,从1到4–9和10 您将如何在MySql结果或任何DBMS中的一行中可视化关系


对于分层结果,我能想到的唯一明智的选择是XML,但您不想去那里,因为它可以在PHP中的base record.parent结构上做得更好,而不是解析XML。

可能类似于此,根据需要添加级别:

SELECT 
    d1.*, 
    d2.`name` AS '2nd Level', 
    d3.`name` AS 'Top Level'
    FROM `my_table` AS d1 
    LEFT JOIN `my_table` AS d2 ON d1.parent_id=d2.id 
    LEFT JOIN `my_table` AS d3 ON d2.parent_id=d3.id

递归查询在Oracle和最新的PostgreSQl上也可用,但在MySQL上不可用。