- ベストアンサー
複数のレコードをimplodeでまとめる方法
ほんと度々すいません…。 http://oshiete1.goo.ne.jp/qa3574682.htmlで一度解決したのですが、私の質問の仕方が悪く、結局実用できなかったので再度質問させてください。 上記URLでやったことに、更にフィールドが増えた場合の記述方法についてです。 table1 【ID|field1】 [1|AAA] [1|BBB] [2|CCC] [3|DDD] [3|EEE] [3|FFF] table2 【ID|field2】 [1|ooo] [2|ppp] [2|qqq] [2|rrr] [3|sss] [3|ttt] ↑構造が同じだけど内容が違うテーブルが5つあります(table1~table5まで)。そしてこれらのテーブルをクエリでは↓ <table> <tr><th>ID</th> <th>field1</th> <th>field2</th> <th>field3</th> <th>field4</th> <th>field5</th></tr> <tr><td>1</td> <td>AAA<br>BBB</td> <td>ooo</td> ・・・</tr> <tr><td>2</td> <td>CCC</td> <td>ppp<br>qqq<br>rrr</td> ・・・</tr> <tr><td>3</td> <td>DDD<br>EEE<br>FFF</td> <td>sss<br>ttt</td> ・・・</tr> </table> というように表示するのが理想です。 一応自分で考えましたが、できなかったので…お願いします。 ============================== 一応、前回http://oshiete1.goo.ne.jp/qa3574682.htmlにて頂いた回答をまとめたコードが↓です。 (table1のみの場合だとこうなります)→mr_araki様に感謝しております。 $query = mysql_query($sql); $rows = array(); while ($row = mysql_fetch_assoc($query)) { if (!isset($rows[$row[ID]])) { $rows[$row[ID]] = array(); } $rows[$row[ID]][] = $row[field1]; } echo "<table>\n"; echo "<tr><th>ID</th><th>field1</th></tr>\n"; foreach ($rows as $id => $row) { echo "<tr><td>" .$id. "</td><td>" .implode('<br>', $row). "</td></tr>\n"; } echo "</table>";
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
重複が有るデータを同様に動かすなら、 mysqlから取ってきた値を $Data["field1"] = array( array("AAA",1), array("AAA",1), ・ ・ ・ ); のように配列の中にペアの配列を入れる形に変更して スクリプトの二番目のforeach内で値をリストで分けて取り出し、 あとは同じままです。 テストに使用したソースを載せておきます。 <?php $Data["field1"] = array( array("AAA",1), array("AAA",1), array("CCC",2), array("DDD",3), array("EEE",3), array("FFF",3), array("AAA",1) ); $Data["field2"]= array( array("ooo",1), array("ppp",2), array("qqq",2), array("rrr",2), array("sss",3), array("ttt",3) ); $Data["field3"]= array( array("111",1), array("222",2), array("333",2), array("444",2), array("555",3), array("666",3) ); $header = array_keys($Data); foreach((array)$header as $title){ $tHeader .= "<th>$title</th>\n"; } foreach($Data as $field => $F){ foreach($F as $values){ list($value,$no) = $values; $R[$no][$field][] = $value; } } foreach ($R as $fld => $ary){ $tBody .="</tr>\n<tr><td>$fld</td>\n"; foreach($ary as $key =>$data){ $o = implode("<br>",$data); $tBody .= "<td>$o</td>\n"; $xkey = $key; } } $tBody .= "</tr>\n"; echo <<< EOF <table border ="1" cellspacing = "0" cellpadding = "0"> <tr><th>ID</th> $tHeader $tBody </table> EOF; ?>
その他の回答 (2)
- fa-ce
- ベストアンサー率42% (9/21)
フィールドの値はIDに対して一意であると想定して、 以下のようなプログラムを組んで見ました。 当方mysqlはインストールしていませんので、 mysql_fetch_assocで取ってきた値を $Data["フィールド名"]["値"]=1 のように$Dataという変数に入れたと想定しています。 fieldの数はいくつでも変更ができますが細かなテストはしていません。 まるまるコピーして動かしてみてください。 <?php $Data["field1"] = array( "AAA"=>1, "BBB"=>1, "CCC"=>2, "DDD"=>3, "EEE"=>3, "FFF"=>3 ); $Data["field2"]= array( "ooo"=>1, "ppp"=>2, "qqq"=>2, "rrr"=>2, "sss"=>3, "ttt"=>3 ); $Data["field3"]= array( "111"=>1, "222"=>2, "333"=>2, "444"=>2, "555"=>3, "666"=>3 ); $header = array_keys($Data); foreach((array)$header as $title){ $tHeader .= "<th>$title</th>\n"; } foreach($Data as $field => $F){ foreach($F as $value =>$id){ $R[$id][$field][] = $value; } } foreach ($R as $fld => $ary){ $tBody .="</tr>\n<tr><td>$fld</td>\n"; foreach($ary as $key =>$data){ //var_dump($data); $o = implode("<br>",$data); $tBody .= "<td>$o</td>\n"; $xkey = $key; } } $tBody .= "</tr>\n"; echo <<< EOF <table border ="1" cellspacing = "0" cellpadding = "0"> <tr><th>ID</th> $tHeader $tBody </table> EOF; ?>
補足
コードを解読するのとMYSQLで実践するのに手こずりましたが… 素人の自分としては考えもしなかった方法でしたが、理屈はわかりました。回答ありがとうございます。 ところでこの方法だと、一つのフィールドに同じ値があった場合、 (たとえばfield1の最初に"AAA"がありますが、またあとで"AAA"が出てきた場合。2回だけでなく何回も出てくることを前提とする) 配列の添字に同じものは二回以上使えないことから、正しく機能しませんよね…? これを解決するための改良法とか、ないでしょうか?
- yexob328
- ベストアンサー率25% (1/4)
↓のようなことでしょうか。 見当違いだったらすみません。 //表示するフィールド名 $field_arr = array('field1', 'field2', 'field3', 'field4', 'field5'); while ($row = mysql_fetch_assoc($query)) { if (!isset($rows[$row[ID]])) { $rows[$row[ID]]['field1'] = array(); } $rows[$row[ID]]['field1'][] = $row[field1]; } と、フィールド名で括っておいて、 ・ ・ ・ //表示 echo "<table>\n"; echo "<tr><th>ID</th>\n"; foreach ($field_arr as $field_name) { echo"<th>{$field_name}</th>\n"; } echo "</tr>\n"; foreach ($rows as $id => $row) { echo "<tr><td>" .$id. "</td>\n"; foreach ($field_arr as $field_name) { echo "<td>" .implode('<br>', $row[$field_name]). "</td>\n"; } echo "</tr>\n"; } echo "</table>";
補足
ありがとうございます、それのことです! 大方は思い通りにできているんですが、今回頂いたコードだと、 <tr><td>1</td> <td>AAA<br>BBB</td> <td>ooo<br>ooo</td> ・・・</tr> <tr><td>2</td> <td>CCC<br>CCC<br>CCC</td> <td>ppp<br>qqq<br>rrr</td> ・・・</tr> <tr><td>3</td> <td>DDD<br>DDD<br>EEE<br>EEE<br>FFF<br>FFF</td> <td>sss<br>ttt<br>sss<br>ttt<br>sss<br>ttt</td> ・・・</tr> というふうに、レコードがダブって表示される(?)といいますか、一番行数が多いフィールドに合わせて他のフィールドの行数が増えているといいますか…。 これってどうにかならないでしょうか? 引き続き皆様の回答お待ちしてます。
お礼
素早い回答ありがとうございます。 mysqlから取り出した値を$Dataに上手く格納できずに苦労しましたが、どうにか理想形に辿り着きました。 自分の覚え書きのために、補足のところに完成形のコード入れときます。 お2方、本当にありがとうございました。
補足
// field1 $sql = "SELECT id,table1.field AS field1 FROM table0"; $result = mysql_query($sql); while ($row = mysql_fetch_assoc($result)) { $Data["field1"][] = array($row[field1],$row[id]); } // field2 $sql = "SELECT id,table2.field AS field2 FROM table0"; $result = mysql_query($sql); while ($row = mysql_fetch_assoc($result)) { $Data["field2"][] = array($row[field2],$row[id]); } // field3 $sql = "SELECT id,table3.field AS field3 FROM table0"; $result = mysql_query($sql); while ($row = mysql_fetch_assoc($result)) { $Data["field3"][] = array($row[field3],$row[id]); } $header = array_keys($Data); foreach((array)$header as $title){ $tHeader .= "<th>$title</th>\n"; } foreach($Data as $field => $F){ foreach($F as $values){ list($value,$no) = $values; $R[$no][$field][] = $value; } } foreach ($R as $fld => $ary){ $tBody .="</tr>\n<tr><td>$fld</td>\n"; foreach($ary as $key =>$data){ $o = implode("<br>",$data); $tBody .= "<td>$o</td>\n"; $xkey = $key; } } $tBody .= "</tr>\n"; echo <<< EOF <table border ="1" cellspacing = "0" cellpadding = "0"> <tr><th>ID</th> $tHeader $tBody </table> EOF;