当前位置: 首页 > 面试题库 >

使用带有mysql查询结果的php获取父级下的所有子级,孙级等节点

周瀚
2023-03-14
问题内容

我一直在试图解决这个问题,但是我什么都没走,希望有人可以救我。

我的问题是我正在使用邻接列表数据模型在mysql中生成我的层次结构数据。我可以将表(见下文)检索到多维数组中,并且每个项目都具有关联数组。我想要做的就是一旦得到这个数组,我想得到另一个数组,其所有节点(子,孙等)都位于父ID(包括父项)下。我只是无法锻炼如何在其中编写代码的PHP。

在MySQL中,我的表如下所示:

id     name       parent_id
1  Electronics          0
2  Televisions          1
3  Portable Electronics 1
4  Tube                 2
5  LCD                  2
6  Plasma               2
7  Mp3 Players          3
8  CD Players           3
9  2 Way Radios         3
10 Flash                7

我可以使用此代码将所有行检索到与此相关的数组中。

$r = mysql_query("SELECT * FROM test ");
        $data = array();
        while($row = mysql_fetch_assoc($r)) {
         $data[] = $row;
         }

获得结果:

Array 
( 
    [0] => Array 
    ( 
        [id] => 1 
        [name] => Electronics 
        [parent_id] => 0 
    ) 
    [1] => Array 
    ( 
        [id] => 2 
        [name] => Televisions 
        [parent_id] => 1 
    ) 
    [2] => Array 
    ( 
        [id] => 3 
        [name] => Portable Electronics 
        [parent_id] => 1 
    )
    [3] => Array 
    (
        [id] => 4 
        [name] => Tube 
        [parent_id] => 2 
    )
    [4] => Array 
    (
        [id] => 5 
        [name] => LCD 
        [parent_id] => 2
    )
    [5] => Array
    (
        [id] => 6 
        [name] => Plasma 
        [parent_id] => 2
    )
    [6] => Array
    (
        [id] => 7 
        [name] => Mp3 Players 
        [parent_id] => 3 
    )
    [7] => Array 
    (
        [id] => 8 
        [name] => CD Players 
        [parent_id] => 3
    )
    [8] => Array 
    (
        [id] => 9 
        [name] => 2 Way Radios 
        [parent_id] => 3
    )
    [9] => Array
    (
        [id] => 10 
        [name] => Flash 
        [parent_id] => 7 
    ) 
)

有了这些结果,我想用一个ID将其过滤掉。

举例来说,我想要便携式电子设备下每个节点的ID为3的关联数组。(使用ID作为代码)

它将返回一个包含ID为行的数组:

  • 3便携式电子产品(必须包括选定的母体)
  • 7 Mp3播放器(儿童)
  • 8个CD播放器(儿童)
  • 9 2路收音机(儿童)
  • 10 Flash(大孩子)

如果Flash有孩子,它将也返回那些孩子。

因此,最终结果将返回与上面的数组类似的数组,但是仅包含那些项。

请注意:我没有使用创建树结构的多维数组的函数(已经有解决方案)。我想构建一个函数:fetch_recursive($
id)来接收ID并返回其中的所有项目该级别以及以下级别等

希望这可以帮助

提前致谢


问题答案:

编辑:

之前,我曾发布过一种解决方案,可以从您提供的输出中构建多维数组,以及一种id从特定数组中获取特定子元素的方法。现在,我已经弄清楚了如何直接从输出中检索子元素(而不必首先通过一个buildtree()函数:

function fetch_recursive($src_arr, $currentid, $parentfound = false, $cats = array())
{
    foreach($src_arr as $row)
    {
        if((!$parentfound && $row['id'] == $currentid) || $row['parent_id'] == $currentid)
        {
            $rowdata = array();
            foreach($row as $k => $v)
                $rowdata[$k] = $v;
            $cats[] = $rowdata;
            if($row['parent_id'] == $currentid)
                $cats = array_merge($cats, fetch_recursive($src_arr, $row['id'], true));
        }
    }
    return $cats;
}

要使用上面的函数,只需将输出数组传递$data给第一个参数,然后id您要从第二个参数中检索子元素:

例如:

$list = fetch_recursive($data, 3);

哪个应该为您提供正确的数组结构id 3(如该答案最后一个代码框中的示例所示)。

原始答案:

到目前为止,我从来没有写过一个递归函数来从此设计中构建嵌套树。我敢肯定还有很多其他人编写了类似的函数,但是这个绝对可以为您工作:

function buildtree($src_arr, $parent_id = 0, $tree = array())
{
    foreach($src_arr as $idx => $row)
    {
        if($row['parent_id'] == $parent_id)
        {
            foreach($row as $k => $v)
                $tree[$row['id']][$k] = $v;
            unset($src_arr[$idx]);
            $tree[$row['id']]['children'] = buildtree($src_arr, $row['id']);
        }
    }
    ksort($tree);
    return $tree;
}

此函数将在邻接表之外递归地构建树,并保持ID的升序排列。这也使id每个父/子的成为每个信息数组的键。

这段代码:

$r = mysql_query("SELECT * FROM test ");
$data = array();
while($row = mysql_fetch_assoc($r)) {
    $data[] = $row;
}
echo '<pre>';
print_r(buildtree($data));
echo '</pre>';

将输出如下内容:

Array 
(
    [1] => Array 
    (
        [id] => 1
        [name] => Electronics 
        [parent_id] => 0 
        [children] => Array
        (
            [2] => Array 
            ( 
                [id] => 2
                [name] => Televisions 
                [parent_id] => 1 
                [children] => Array
                (
                    [4] => Array 
                    (
                        [id] => 4
                        [name] => Tube 
                        [parent_id] => 2
                        [children] => Array()
                    )
                    [5] => Array 
                    (
                        [id] => 5
                        [name] => LCD 
                        [parent_id] => 2
                        [children] => Array()
                    )
                    [6] => Array
                    (
                        [id] => 6
                        [name] => Plasma 
                        [parent_id] => 2
                        [children] => Array()
                    )
                )
            )
            [3] => Array 
            (
                [id] => 3
                [name] => Portable Electronics 
                [parent_id] => 1
                [children] => Array
                (
                    [7] => Array
                    (
                        [id] => 7
                        [name] => Mp3 Players 
                        [parent_id] => 3 
                        [children] => Array
                        (
                            [10] => Array
                            (
                                [id] => 10
                                [name] => Flash 
                                [parent_id] => 7
                                [children] => Array()
                            ) 
                        )
                    )
                    [8] => Array 
                    (
                        [id] => 8
                        [name] => CD Players 
                        [parent_id] => 3
                        [children] => Array()
                    )
                    [9] => Array 
                    (
                        [id] => 9
                        [name] => 2 Way Radios 
                        [parent_id] => 3
                        [children] => Array()
                    )
                )
            )
        )
    )
)

要将特定对象的所有子节点放入id一维数组中,可以使用以下函数:

function fetch_recursive($tree, $parent_id, $parentfound = false, $list = array())
{
    foreach($tree as $k => $v)
    {
        if($parentfound || $k == $parent_id)
        {
            $rowdata = array();
            foreach($v as $field => $value)
                if($field != 'children')
                    $rowdata[$field] = $value;
            $list[] = $rowdata;
            if($v['children'])
                $list = array_merge($list, fetch_recursive($v['children'], $parent_id, true));
        }
        elseif($v['children'])
            $list = array_merge($list, fetch_recursive($v['children'], $parent_id));
    }
    return $list;
}

基于上面的buildtree()函数,假设我们要获取所有id3 个子节点:

echo '<pre>';
print_r(fetch_recursive(buildtree($a), 3));
echo '</pre>';

这将输出:

Array
(
    [0] => Array
        (
            [id] => 3
            [name] => Portable Electronics
            [parent_id] => 1
        )

    [1] => Array
        (
            [id] => 7
            [name] => Mp3 Players
            [parent_id] => 3
        )

    [2] => Array
        (
            [id] => 10
            [name] => Flash
            [parent_id] => 7
        )

    [3] => Array
        (
            [id] => 8
            [name] => CD Players
            [parent_id] => 3
        )

    [4] => Array
        (
            [id] => 9
            [name] => 2 Way Radios
            [parent_id] => 3
        )

)


 类似资料:
  • 问题内容: 我正在尝试并寻找 从 Oracle 11g数据库中的层级查询中 从节点获取所有最后一级子级(叶子)的方法 。 我有2个表:“节点”(具有各自值的所有节点的列表)和“关系”,它们指定父子关系: -节点- - 关系 - 我已经阅读了有关CONNECT_BY_ISLEAF的信息,如果它是叶子则返回1,但是我无法像Oracle示例一样查询CONNECT_BY_ISLEAF,但我没有得到任何结果

  • 我把这张桌子填满了 当选择IDFolder=1的文件夹时,应该为返回此文件夹的所有子文件夹和子文件夹(2,3,4,5,6,7) 当我选择文件夹id=4==>(5,7,6)时

  • 本文向大家介绍如何使用jQuery从父级删除所有子级节点?,包括了如何使用jQuery从父级删除所有子级节点?的使用技巧和注意事项,需要的朋友参考一下 要从父级删除所有子节点,请使用方法。该方法从匹配的元素集中删除所有子节点。 示例 您可以尝试运行以下代码以了解如何从父级删除所有子节点-

  • 问题内容: 我有一个具有以下字段的MySQL表: 其中父字段表示上层ID。例如,水果id是1,橙色是水果之一,因此父对象是1。 但是我想做一个有效的MySQL查询来获取所有记录,格式为parent-> children-> parent-> children格式。我怎样才能做到这一点? 查询的结果记录应类似于: 问题答案: 您需要mysql不支持的递归联接。您唯一可以做的就是确定最大深度(由于p-

  • 问题内容: 表-用户 列-(userId,name,managerId) 行- 如果我提供用户ID,则应列出所有向他报告的人。如果我给userId = 2,则应返回3,4。 这个查询正确吗 有什么有效的方法来管理DB中的树结构吗?左右叶方式怎么样? 问题答案: 在我看来,邻接列表模型的问题在于,在SQL中很难处理它,尤其是当您不知道树结构的嵌套深度时。 您提到的“左右叶方式”可能是嵌套集合模型,它

  • 问题内容: 我的数据库中有一个页面表,每个页面可以有一个父项,如下所示: 如果选择一个以上级别,那么最好的MySQL查询是最好的选择父级,子级,子级顺序的所有页面的查询,最多三个级别。上面的示例将产生所需的顺序: 问题答案: 我认为您应该在表中再添加一个字段,称为level并将其存储在节点的level中,然后按级别然后按父级对查询进行排序。