人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHP MySQL(4.1)の質問です

テーブル名
school_date

フィールド
id
ken(東京都・神奈川県など)
area(新宿区・渋谷区など)
name(学校名)
他多数


このようなテーブルがあります。
そして実際にはこのようにデータが入っています。

1 東京都 新宿区 新宿高校・・・
2 東京都 渋谷区 渋谷高校・・・
3 東京都 新宿区 新宿御苑高校・・・
4 東京都 中央区 日本橋高校・・・
5 東京都 新宿区 歌舞伎町高校・・・
6 東京都 渋谷区 センター街高校・・・


----------
やりたい事
PHPで以下のようにHTML出力させたいです。


新宿区
新宿高校
新宿御苑高校
歌舞伎町高校

渋谷区
渋谷高校
センター街高校

中央区
日本橋高校


新宿区・渋谷区のようなareaの項目を1度だけ表示させるのが難しくてできません。
このように出力する事は可能でしょうか??
500ポイントほど用意致します。
よろしくお願いします。

●質問者: tokyosmash
●カテゴリ:インターネット ウェブ制作
✍キーワード:Area HTML ken MySQL name
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● Mook
●200ポイント

やれないことはありませんが、必ずしも一回のクエリでやる必要はありません。

ときにはステップごとに処理をするほうが、問題を簡単にしてくれます。


いずれにせよクエリだけでは、ご希望のようにはできないので、PHP側の処理になるでしょう。

<?
// データベース情報
define( "db_Server", "localhost" );
define( "db_User", "foo" );
define( "db_Password", "bar" );
define( "db_Name", "testdb" );

// データベース接続
$conn = mysql_connect( db_Server, db_User, db_Password ) or die("接続エラー");
mysql_select_db(db_Name) or die("DATABASE 選択エラー :".$dbName );

// エリアを表示
$sql = "SELECT DISTINCT ken, area FROM school_data ORDER BY ken;";
$res = mysql_query( $sql, $conn ) or die("エリアデータ抽出エラー<br>\n".$sql);
while ( $row = mysql_fetch_array( $res, MYSQL_ASSOC ) ) {
 print $row["area"]."<br>\n";
// エリア内の高校を表示
 $sql = "SELECT name FROM school_data WHERE area = '".$row["area"]."';";
 $sres = mysql_query( $sql, $conn ) or die("名前抽出エラー");
 while ( $srow = mysql_fetch_array( $sres, MYSQL_ASSOC ) ) {
 print "&nbsp;&nbsp;".$srow["name"]."<br>\n";
 }
 print "<br>\n";
}
mysql_close( $conn );
?>

一度のクエリで処理をしたければ、area順でデータを取得し、

area を見ながら変わったら表示をする、というような処理に

なると思います。


2 ● tobeoscontinue
●50ポイント

連想配列(keyが文字列)を使ってみました。

function array_nest($datas)
{
 foreach($datas as $data) {
 list($ken, $area, $name) = $data;
 $nest["$ken"]["$area"][] = $name;
 }
 return $nest;
}

二次元の配列を二次元の?連想配列に変換します。(名前はダメダメです。いいのが思いつかない)

この時点で東京や区名など同じもの(名前が同じ)は一つだけになります。

$res = array(
 array('東京都','新宿区','新宿高校'),
 array('東京都','渋谷区','渋谷高校'),
 array('東京都','新宿区','新宿御苑高校'),
 array('東京都','中央区','日本橋高校'),
 array('東京都','新宿区','歌舞伎町高校'),
 array('東京都','渋谷区','センター街高校')
);

サンプルとしてこのような二次元の配列を考えます。SQLの結果としても同じようなものを受け取ることは可能だと思います。

$nest = array_nest($res);
foreach ($nest as $ken => $a_ken) {
 echo $ken."<br>";
 foreach ($a_ken as $area => $a_area) {
 echo '&nbsp;'.$area."<br>";
 foreach ($a_area as $name) {
 echo '&nbsp;&nbsp;'.$name."<br>";
} } }

表示はちょっと長いです。

肝は

$nest["$ken"]["$area"][] = $name;

の部分で連想配列を使うことで重複する部分を判断することなく一つにできることです。

SQLの結果から直接$nestの連想配列を作った方がコードが短くなるとは思います。がコードの再利用などを考えると単純な構造を経由したほうが後々便利だとは思ます。


3 ● nandedarou
●300ポイント ベストアンサー

テーブル名のschool_dateは、school_dataの書き間違いですか?

とりあえず、質問文のとおり、school_dateにしておきます。

テーブル名のschool_dateは、school_dataの書き間違いですか?
とりあえず、質問文のとおり、school_dateにしておきます。
>||
// 東京の全てのデータをとりだすSQL文。
// ※ORDER BYでarea順に並べて、同じareaのデータが連続するようにしておく
$ken = '東京都';
$sql = sprintf("SELECT * FROM school_date WHERE ken = '%s' ORDER BY area;", $ken);

// SQL文を実行し、連想配列として$dataに保存
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result)) {
 $data[] = $row;
}

// 表示処理
$printed_area = ''; // 初期化
foreach( $data as $key => $value ){
 
 // ※前に表示したareaと違ったら、areaを表示する。
 if($printed_area <> $value['area']){
 
   // 最初は、改行しないが、2個目以降のareaの前に改行する
 if($printed_area<>'') print "<br>";
 
 // areaを表示する
 print $value['area'].'<br>';
 
 // ※表示したareaは、printed_areaに保存する
 $printed_area = $value['area'];
 
 }
 
 // 学校名を表示する
 print '&nbsp;&nbsp;'.$value['name'].'<br>';
 
}

上記3つの※印の部分がポイントです。

いかがでしょうか?

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ