0

階層データを持つように設定された 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
        )
)
4

2 に答える 2

0

他の人も述べたように、プレーンな 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);

それはそれについてです。お役に立てば幸いです。

于 2013-09-27T21:27:59.973 に答える