2013-09-25 18 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); 

就是這樣。我希望它能幫助你。

相關問題