2013-09-25 19 views
0

我有4个表设置为具有分层数据。我试图通过连接返回数据,并找到一种可重用的方式从结果中获取多维数组,以便将来使用不同的表格布局。最终我想把它当作json吐出来。有没有一个好的方法来做到这一点?我怎样才能从包含多个连接的mysql查询在php中获取多维数组

这里是我的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 
     ) 
) 
+0

你不会从普通的'SQL'中获得。只需查询您的数据,然后在PHP中构建更精细的构造。如果你可以假设'levelN_names'对于这个级别是唯一的,那么'foreach'循环应该就足够了,否则你可能需要'id'和每个级别的'name'&'children'条目工作。 – Wrikken

+0

我想我在问,如果有人有一个类或函数可以用更抽象的方法做到这一点。我可以正确地命名所有东西,并将其转化为我正在寻找的东西,但每当表结构发生变化时我都必须重新编写它。 – emanate

+0

那么,如果你需要一个完整的邻接列表树,[我的答案在这里工作得很好](http://stackoverflow.com/a/13888486/358679),但是,像你正在查询它的那个子树可以工作不太好。我会考虑这一点... – Wrikken

回答

0

要么分开您的查询。或者使用字段名称的前缀将它们添加到不同的对象中 将level1_id重命名为level_1_id,这样可以更容易地使用爆炸和一对for循环解析数字

0

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

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

但在此之前,考虑下列因素:

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

这应该从指定$table返回所有数据,在关联数组的数组,其前提是$fieldnull。如果不是,则应该应用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); 

就是这样。我希望它能帮助你。

相关问题