如何使用PHP将MySQL查询结果作为嵌套数组获取?

如何使用PHP将MySQL查询结果作为嵌套数组获取?,php,mysql,arrays,Php,Mysql,Arrays,假设我有一个简单的表,其中pos_level是位置的级别,pos_under是它上面位置的PID 在第一级,我有“总经理”和“主管” 在第二级,在“总经理(PID:1)”下:“助理经理”,在“主管(PID:2)”下:“营销” 在第3级,在“助理经理(PID:3)”下:“销售”和“采购”,在“营销(PID:2)”下:无 现在,我如何进行查询,以便得到一个嵌套数组作为结果,如下所示: Array ( [0] => Array ( [pos_lev

假设我有一个简单的表,其中pos_level是位置的级别,pos_under是它上面位置的PID

在第一级,我有“总经理”和“主管”

在第二级,在“总经理(PID:1)”下:“助理经理”,在“主管(PID:2)”下:“营销”

在第3级,在“助理经理(PID:3)”下:“销售”和“采购”,在“营销(PID:2)”下:无

现在,我如何进行查询,以便得到一个嵌套数组作为结果,如下所示:

Array
(
    [0] => Array
        (
            [pos_level] => 1
            [pos_name] => General Manager
            [pos_under] => Array
                (
                    [0] => Array
                        (
                            [pos_level] => 2
                            [pos_name] => Asst. Manager
                            [pos_under] => Array
                                (
                                    [0] => Array
                                        (
                                            [pos_level] => 3
                                            [pos_name] => Sales
                                        )

                                    [1] => Array
                                        (
                                            [pos_level] => 3
                                            [pos_name] => Purchase
                                        )

                                )

                        )

                )

        )

    [1] => Array
        (
            [pos_level] => 1
            [pos_name] => Supervisor
            [pos_under] => Array
                (
                    [0] => Array
                        (
                            [pos_level] => 2
                            [pos_name] => Marketing
                            [pos_under] => Array
                                (
                                )

                        )

                )

        )

)
我尝试过使用多个查询并使用结果使用array_push,但我有大约100多个pos_名称,我认为这很混乱,我还尝试过使用loop来为每个级别和更低级别运行查询,还尝试过为每个级别使用多个表,但我希望我只能使用1个表,并且能够查询结果作为上面的嵌套数组,以便在我的应用程序中进一步使用


欢迎您提供所有答案、意见和建议。谢谢。

正如上面评论中提到的,我总的来说怀疑您所采用的方法是否是一种好方法。那是因为它不会扩展!您尝试从数据库中获取所有条目,并将它们打包到单个分层数组中。这意味着您要在内存中为每个条目创建多个副本。随着参赛作品数量的增加,将会发生什么?您将面临脚本内存消耗不断增加的问题,这显然会使脚本最终失败

尽管如此,我还是接受了这个挑战,并实现了一个小演示,演示了如何借助于引用巧妙地构造这样的嵌套结构。这样的引用不仅简化了嵌套结构的创建,还通过防止重复按值复制条目来减少内存占用。然而,这并不能解决上述方法的一般缩放问题,它只能帮助减少它

我还冒昧地对您的方法进行了一个小修改,并引入了一个新属性“pos_over”,用于在条目下保存条目。原因有二:

  • 删除原始可用数据通常不是一个好主意,尤其是不要用修改过的含义替换它
  • 术语“pos_under”的含义是描述给定条目(将)放置在什么其他条目下。但是从“上面”的条目来看,“下面”的条目不应该被“下面的位置”引用,对吗?这将与该术语的原始含义相矛盾 以下代码不依赖于数据库进行演示。相反,它从CSV字符串中读取原始数据并对其进行解析。所需结构的实际建筑用注释进一步向下标记。还应该提到的是,代码期望原始数据仅在声明其他条目之后才引用它们。因此,如果从上到下处理另一个条目下的每个条目,可以预期另一个条目已经存在

    请注意,构建嵌套结构的实际代码仅由12行巧妙的代码组成

    <?php
    
    // the raw CSV data
    $csvText = <<<CSV
    PID|pos_name|pos_level|pos_under
    1|General Manager|1|0
    2|Supervisor|1|0
    3|Asst. Manager|2|1
    4|Sales|3|3
    5|Purchase|3|3
    6|Marketing|2|2
    CSV;
    
    // praparation of CSV data
    foreach (explode("\n", $csvText) as $csvRow) {
        $csvData[] = str_getcsv($csvRow, '|');
    }
    $csvTitle = array_shift($csvData);
    
    $table = [];
    foreach ($csvTitle as $titleKey=>$titleValue){
        foreach ($csvData as $csvRow=>$csvColumn) {
            foreach ($csvColumn as $csvKey=>$csvValue) {
                $table[$csvRow][$csvTitle[$csvKey]] = $csvValue;
            }
        }
    }
    
    // creation of the structure
    $catalog = [];
    $structure = [];
    foreach ($table as $key=>&$entry) {
        $entry['pos_over'] = [];
        if ($entry['pos_under'] == 0) {
            $structure[] = &$entry;
            $catalog[$entry['PID']] = &$structure[count($structure)-1];
        } else {
            $catalog[$entry['pos_under']]['pos_over'][] = &$entry;
            $catalog[$entry['PID']] = &$catalog[$entry['pos_under']]['pos_over'][count($catalog[$entry['pos_under']]['pos_over'])-1];
        }
    }
    
    // demonstration output
    print_r($structure);
    

    可以有多少个级别?另外,请显示您在MySQL中期望的实际输出。您需要自己构造嵌套数组。我认为任何php函数都不会从SQL查询返回多级数组,SQL查询也不会返回二维表状结构。我总的来说怀疑您所采用的方法是否是一种好方法。那是因为它不会扩展!您尝试从数据库中获取所有条目,并将它们打包到单个分层数组中。这意味着您要在内存中为每个条目创建多个副本。随着参赛作品数量的增加,将会发生什么?您的脚本内存消耗不断增加,这显然会使它最终失败。@TimBiegeleisen到目前为止只有3个级别,但可能会变成4个级别。感谢您的精彩回答,是的,对不起,应该在数组中使用pos_over key,然而,我希望有一个更简单的解决方案,比如只使用MySql查询,因为在其他一些函数中,我需要立即循环这个数组(也使用循环生成),我认为这个过程可能需要大量内存。无论如何,我也会尝试使用你的循环方法。谢谢@Charas请注意,所示方法的重要方面不是循环,这些都是琐碎的。它是使用引用而不是条目的副本。。。
    <?php
    
    // the raw CSV data
    $csvText = <<<CSV
    PID|pos_name|pos_level|pos_under
    1|General Manager|1|0
    2|Supervisor|1|0
    3|Asst. Manager|2|1
    4|Sales|3|3
    5|Purchase|3|3
    6|Marketing|2|2
    CSV;
    
    // praparation of CSV data
    foreach (explode("\n", $csvText) as $csvRow) {
        $csvData[] = str_getcsv($csvRow, '|');
    }
    $csvTitle = array_shift($csvData);
    
    $table = [];
    foreach ($csvTitle as $titleKey=>$titleValue){
        foreach ($csvData as $csvRow=>$csvColumn) {
            foreach ($csvColumn as $csvKey=>$csvValue) {
                $table[$csvRow][$csvTitle[$csvKey]] = $csvValue;
            }
        }
    }
    
    // creation of the structure
    $catalog = [];
    $structure = [];
    foreach ($table as $key=>&$entry) {
        $entry['pos_over'] = [];
        if ($entry['pos_under'] == 0) {
            $structure[] = &$entry;
            $catalog[$entry['PID']] = &$structure[count($structure)-1];
        } else {
            $catalog[$entry['pos_under']]['pos_over'][] = &$entry;
            $catalog[$entry['PID']] = &$catalog[$entry['pos_under']]['pos_over'][count($catalog[$entry['pos_under']]['pos_over'])-1];
        }
    }
    
    // demonstration output
    print_r($structure);
    
    Array
    (
        [0] => Array
            (
                [PID] => 1
                [pos_name] => General Manager
                [pos_level] => 1
                [pos_under] => 0
                [pos_over] => Array
                    (
                        [0] => Array
                            (
                                [PID] => 3
                                [pos_name] => Asst. Manager
                                [pos_level] => 2
                                [pos_under] => 1
                                [pos_over] => Array
                                    (
                                        [0] => Array
                                            (
                                                [PID] => 4
                                                [pos_name] => Sales
                                                [pos_level] => 3
                                                [pos_under] => 3
                                                [pos_over] => Array
                                                    (
                                                    )
    
                                            )
    
                                        [1] => Array
                                            (
                                                [PID] => 5
                                                [pos_name] => Purchase
                                                [pos_level] => 3
                                                [pos_under] => 3
                                                [pos_over] => Array
                                                    (
                                                    )
    
                                            )
    
                                    )
    
                            )
    
                    )
    
            )
    
        [1] => Array
            (
                [PID] => 2
                [pos_name] => Supervisor
                [pos_level] => 1
                [pos_under] => 0
                [pos_over] => Array
                    (
                        [0] => Array
                            (
                                [PID] => 6
                                [pos_name] => Marketing
                                [pos_level] => 2
                                [pos_under] => 2
                                [pos_over] => Array
                                    (
                                    )
    
                            )
    
                    )
    
            )
    
    )