从 MySQL 结果创建分层数组

Posted

技术标签:

【中文标题】从 MySQL 结果创建分层数组【英文标题】:Create Hierarchical Array from MySQL result 【发布时间】:2012-12-20 03:36:24 【问题描述】:

我已经看到其他关于此的问题,但与我的情况不太一样。我在 mysql 中有下表:

   term_id       name           slug                 taxonomy     parent
1             Entry Form     entry-form           format       0
2             Page           page                 format       3
3             Facebook       facebook             format       0
4             Entry Form     facebook-entry-form  format       3
5             Twitter        twitter              format       0
6             Single        single                format       2

我有以下 OBJECT 查询:

$formats = $wpdb->get_results($wpdb->prepare("
    SELECT * FROM table t
    WHERE t.taxonomy = 'format'
"));

我最终得到以下数组:

Array ( [0] => stdClass Object ( [term_id] => 1 [name] => Entry Form [slug] => entry-form [taxonomy] => format [parent] => 0 ) [2] => stdClass Object ( [term_id] => 2 [name] => Page [slug] => page [taxonomy] => format [parent] => 3 ) [3] => stdClass Object ( [term_id] => 3 [name] => Facebook [slug] => facebook [taxonomy] => format [parent] => 0 ) [4] => stdClass Object ( [term_id] => 4 [name] => Entry Form [slug] => entry-form-facebook [taxonomy] => format [parent] => 3 ) [5] => stdClass Object ( [term_id] => 5 [name] => Twitter [slug] => twitter [taxonomy] => format [parent] => 0 ) [6] => stdClass Object ( [term_id] => 6 [name] => Single [slug] => single [taxonomy] => format [parent] => 2 ) ) 1

以上所有内容都需要在输出上转换成一个分层列表,如下所示:

Entry Form
Twitter
Facebook
 - Entry Form
 - Page
 -- Single

因此,我需要将数组 $formats 转换为基于父字段的分层数组。 0 的父项表示它是***项目。因此,由于 Single 的父节点为 2,因此它是 Page 的子节点,而 Page 的父节点又是 3,并且是 Facebook 的子节点。

谁能帮我把我的数组变成一个分层数组,然后告诉我如何循环输出它?

【问题讨论】:

可能你已经解释过了,但我不明白你想要什么输出?你能描述一下输出的 sn-p 吗?您只需要分层形式的名称还是所有数据? 我希望输出与描述的完全相同:分层列表。点赞 报名表 推特 Facebook 专页 单人 【参考方案1】:

如果由于查询量而导致的性能不会成为问题,最简单的解决方案是,您无需执行单个查询来填充数组,而是在层次结构树中为每个节点执行一个查询,添加一个“AND parent = $id",其中 $id 是当前节点的 term_id。比如:

    执行 SELECT WHERE .... AND parent = 0; 对于 1 中的每个结果,$id = term_id,执行选择 WHERE ... AND 父母 = $id 递归重复直到没有更多结果

如果性能是一个问题,您仍然可以将查询转储到您的数组并将相同的算法应用于数组,但如果您真的有这么大的容量,您很可能会遇到内存问题。

【讨论】:

这让我觉得效率更低。原因是如果孩子有 20 层深,我不应该在数据库中运行这么多查询。对我来说这似乎是浪费带宽。 这就是我对性能和查询量发表评论的原因。如果你有 20 层深度但不会为成千上万的用户连续运行算法,你会没事的。但如果是这种情况,将整个结果转储到一个数组中可能会让你出现内存不足和/或分页问题。问题(和答案)的关键是您需要使用的递归算法。 好的,我明白你的意思了。我不知道你所说的递归是什么意思。但我会调查一下。 递归,因为您创建了一个打印元素及其子元素的函数,并从中为每个子元素再次调用相同的函数,以便他们可以打印自己和他们的子元素。如果你不熟悉这个概念,请查一下,这是编程必备的。【参考方案2】:

在从数据库中获取数据时,需要将数据放入 assoc 数组中:

//$groups - result array

$groups = array();

//$record contains the assoc array of the current record
while($record = $result->fetchAssoc()) 
      if (!isset($groups[$record["parent"]]))
      
            $groups[$record["parent"]] = array();
      

      array_push($groups[$record["parent"]], $record);

最后,您将获得一个以父级为键的 assoc 层次结构数组。然后递归遍历,就可以得到结果:

function print_recursively(&$groups, $parent_id, $dashes = '')

    if(isset($groups[$parent_id]))
    
          foreach($groups[$parent_id] as $key => $value)
          
                print $dashes . ' ' . $value["name"];
                print_recursively(&$groups, $value["term_id"], $dashes . '-');
          
    

这段代码我没有测试,但是算法是正确的。

【讨论】:

整个概念对我来说是全新的。我什至不知道从哪里开始这段代码。我不承认任何变量是我使用过的变量。我的 $formats 变量在哪里适合? 首先给我看代码,你从数据库中获取数据。我会试着告诉你,如何修改它。 代码就在那里: $formats = $wpdb->get_results($wpdb->prepare(" SELECT * FROM table t WHERE t.taxonomy = 'format' ")); 你能不能把代码改一下,这样会按顺序得到结果:一行接一行?

以上是关于从 MySQL 结果创建分层数组的主要内容,如果未能解决你的问题,请参考以下文章

从 MySQL 结果创建 PHP 数组

NodeJs 从 MySQL 查询结果创建新数组

从 mysql 结果创建一个 id 数组

如何创建 MySQL 分层递归查询?

如何创建 MySQL 分层递归查询?

从mysql查询php创建数组