こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

MYSQLとPHPによって取得する多次元配列

はじめてご質問させていただきます。
現在以下のようなテーブルが3つあります。

[ tbl1 ]
| tbl1Key | title |
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |

[tbl2]
| tbl2Key | tbl1Key | tbl3Key |
| 1 | 2 | 2 |
| 2 | 3 | 1 |
| 3 | 3 | 4 |
| 4 | 1 | 3 |


[tbl3]
| tbl3Key | value |
| 1 | aaa |
| 2 | bbb |
| 3 | ccc |
| 4 | ddd |

上記のデータソースを元に以下のような結果を得たいと考えています。

array(
array( 'tbl1Key'=>1, 'title'=>'a', 'values' => array( array( 'tbl3Key'=>3, value='ccc' ) ),
array( 'tbl1Key'=>2, 'title'=>'b', 'values' => array( array( 'tbl3Key'=>2, value='bbb' ) ),
array( 'tbl1Key'=>3, 'title'=>'c', 'values' => array( array( 'tbl3Key'=>1, value='aaa'), array( 'tbl3Key'=>4, value='ddd' ) ),
array( 'tbl1Key'=>4, 'title'=>'d', 'values' = > array( array( 'tbl3Key'=> , value='' ) )
)

この場合phpによって
$sql = ("select * from `tbl1`");
$res = mysql_query( $sql, $con );
$data = array();
while( $row =mysql_fetch_object( $res ) )
{
$sql = ("select * from `tbl3`
inner join `tbl2` on `tbl3`.`tbl3Key`=`tbl2`.`tbl3Key`
where `tbl2`.`tbl1Key`={$row->tbl1Key}");
$res2 = mysql_query( $sql, $con );
$tmp = array();
while( $r = mysql_fetch_object( $res2 ) )
{
$tmp[] = $r->value;
}
$row->values = $tmp;
$data = $row;
}

まずtbl1のデータをすべて取り、配列dataに格納する段階で、tbl1と関連付けされたtbl3のvalueを取得し配列tblに格納、それを新しい要素として配列dataにプッシュしている状況です。

こういったテーブルでいうところの1カラムのみ配列で返すような事は、こういったループを使って以外にも可能なのでしょうか。

よろしくお願いいたします。

投稿日時 - 2011-03-20 18:12:20

QNo.6607085

困ってます

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(1)

ANo.1

sql文の発行は一回でやった方が、時間的ロスは少ないと思うのだけど、取得データは基本的には2次元配列になる。そこで、keyチェックしながら、配列作り直しという手順になるかとおもう。
<?php
/* 3つのtable全部連結して一覧tableにする 、tbl1keyカラムでソートしておく */
$sql = <<<SSS
select tbl1.tbl1key as t1key, tbl1.title as t1title, tbl3.tbl3key as t3key, tbl3.title as t3title
from tbl1 left join tbl2 on tbl1.tbl1key = tbl2.tbl1key
left join tbl3 on tbl2.tbl3key = tbl3.tbl3key
order by t1key
SSS;
$res = mysql_query( $sql, $con );
$data = array();
$t1 = ''; $i=-1;
/* $t1: t1keyカラム値の重複チェック用 , $i: $dataの配列添え字用
$data を t1keyカラム値をキーとする連想配列にした方が、これらの変数が不用になるけど
*/
while( $row =mysql_fetch_array( $res ) ){
if( $t1 !== $row['t1key'] ){
$t1 = $row['t1key'];$i ++;
$data[$i] = array('tbl1Key'=>$row['t1key'], 'title'=>$row['t1title']
, 'value'=>array( array('tbl3Key'=>(isset($row['t3key'])?$row['t3key']:''), 'value'=(isset($row['t3title'])?$row['t3title']:'') ) ));
}else{
$data[$i]['value'][] = array('tbl3Key'=>$row['t3key'], 'value'=$row['t3title']);
}
}
var_dump($data);

投稿日時 - 2011-03-20 23:43:53

お礼

無事動作を確認いたしました。
やはりループでチェック、追加という形にならざるを得ないんですね。
GROUP_CONCATを使用し表示時にバラして使用するという方法もやってみましたが、やはりスピード的にはいずれもという感じでした。
とても参考になりました。ありがとうございます!

投稿日時 - 2011-03-21 03:09:17

あなたにオススメの質問