如何从包含多个连接的 mysql 查询中获取 php 中的多维数组


How can I get a multi-dimensional array in php from a mysql query containing multiple joins

我有 4 个表设置为包含分层数据。我正在尝试通过联接获取数据,并找到一种可重用的方法从结果中获取多维数组,将来我可能会将其用于不同的表布局。最终我想把它吐出来作为json。有没有好方法可以做到这一点?

这是我的mySQL代码的示例:

SELECT 
    table1.name as level1_name,
    table1.id as level1_id,
    table2.name as level2_name,
    table2.id as level2_id,
    table3.name as level3_name,
    table3.id as level3_id,
    table4.name as level4_name,
    table4.id as level4_id
FROM
    table1
LEFT JOIN table2    on table2.parentid      = table1.id
LEFT JOIN table3    on table3.parentid      = table2.id
LEFT JOIN table4    on table4.parentid      = table3.id
WHERE
    table1.id = 5

我希望看到这样的结果:

Table1_name
{
    Table2_name {
        Table3_name {
            Table4_name,
            Table4_othername
        }
    }
    Table2_othername {
        Table3_othername {
            Table4_othername,
            Table4_otherothername
        }
    }
}

但我得到的是:

Array
(
    [0] => stdClass Object
        (
            [level1_name] => Lorem
            [level1_id] => x
            [level2_name] => Ipsum
            [level2_id] => x
            [level3_name] => Dolor
            [level3_id] => x
            [level4_name] => Eimet
            [level4_id] => x
        )
    [1] => stdClass Object
        (
            [level1_name] => Lorem
            [level1_id] => x
            [level2_name] => Ipsum
            [level2_id] => x
            [level3_name] => Dolor
            [level3_id] => x
            [level4_name] => Eimet
            [level4_id] => x
        )
    [2] => stdClass Object
        (
            [level1_name] => Lorem
            [level1_id] => x
            [level2_name] => Ipsum
            [level2_id] => x
            [level3_name] => Dolor
            [level3_id] => x
            [level4_name] => Eimet
            [level4_id] => x
        )
)

将查询分开。或者使用字段名称的前缀将它们添加到不同的对象中将level1_id重命名为level_1_id这样就可以更轻松地使用爆炸和几个 for 循环解析数字

正如其他人也提到的,普通SQL不会让你解决这个问题。要生成这样的数组,您需要遍历每个主行的所有详细记录。

您需要的是一个递归函数,它为主/细节层次结构的每个级别构造相应的数组。

但在此之前,请考虑以下事项:

function get_table($table,$field=null,$value=null)
  {
  ....
  }

这应该返回来自指定$table的所有数据,在关联数组数组中,前提是$field null。如果不是,则应应用where $field=$value过滤器。

现在,到多汁的部分。以下函数将遍历主/细节表层次结构,基于 $details 数组并以 $table 开头,可能按 $field=$value 过滤。

function table_tree($table,$arrkey,$details=array(),$field=null,$value=null)    
  {
  $detail=array_shift($details);
  $r=array();
  foreach(get_table($table,$field,$value) as $row)
    {
    $label=$row[$arrkey];
    if($detail)
      $r[$label]=table_tree(
        $detail['table'],
        $detail['label'],
        $details,
        $detail['detailkey'],
        $row[$detail['masterkey']]
        );
    else
      $r[]=$label;
    }
  return $r;
  }

现在,$details参数应该是以下形式的数组:

array(
  array('table'=>..., 'label'=>..., 'detailkey'=>..., 'masterkey'=>...),
  /* etc */
  );

每个详细信息级别都应该有一个条目,其中包含以下字段:

  • table:明细表名称

  • label:应该用于生成数组键的字段

  • detailkey:将详细信息行链接到主条目的字段

  • masterkey:主表的字段,用于筛选详细信息

对于您的示例,您需要执行以下操作:

$master_table='table1';
$hierarchy=array(
  array('table'=>'table2','label'=>'name','detailkey'=>'parentid','masterkey'=>'id'),
  array('table'=>'table3','label'=>'name','detailkey'=>'parentid','masterkey'=>'id'),
  array('table'=>'table4','label'=>'name','detailkey'=>'parentid','masterkey'=>'id'),
  );
$result=table_tree($master_table,'name',$hierarchy);

仅此而已。我希望它对你有所帮助。