SQLで複数のテーブルからデータを取得する方法

このQ&Aのポイント
  • 複数のテーブルに対してSQLを使用してデータを取得する方法について解説します。
  • サンプルデータベースとして、sample_dbテーブルとsample_studentsテーブルを使用します。
  • また、ソースコードも示し、指定した表示結果に変更する方法についても説明します。
回答を見る
  • ベストアンサー

複数のテーブルに対しSQLでデータを取得する方法

下記の2つのテーブル、及びソースコードがあります。 【sample_db】 CREATE TABLE IF NOT EXISTS `sample_db` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(64) NOT NULL, `path` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `path` (`path`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ; INSERT INTO `sample_db` (`id`, `name`, `path`) VALUES (1, '2010年', '.1.'), (2, '6月', '.1.2.'), (3, '28日', '.1.2.3.'); 【sample_students】 CREATE TABLE IF NOT EXISTS `sample_students` ( `id` int(11) NOT NULL AUTO_INCREMENT, `sample_db_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ; INSERT INTO `sample_students` (`id`, `sample_db_id`) VALUES (1, 1), (2, 2), (3, 3); 【ソースコード】 <body> <?php $link = mysql_connect('localhost', 'データベースユーザ名', 'データベースパスワード名'); mysql_select_db('データベース名', $link); $sql = <<<SSS SELECT `SampleDb`.`id` , `SampleDb`.`name` , `SampleDb`.`path` , `sample_students`.`id_count` FROM `sample_db` AS `SampleDb` LEFT JOIN ( SELECT count( `sample_db_id` ) AS `id_count` , `sample_db_id` AS `sample_db_id` FROM `sample_students` GROUP BY `sample_db_id` ) AS `sample_students` ON ( `SampleDb`.`id` = `sample_students`.`sample_db_id` ) ORDER BY `SampleDb`.`path` SSS; $query = mysql_query($sql, $link); $p = 0; while ($row = mysql_fetch_array($query)) { $starter= "\n"; $rp = intval( $row['depth'] ); if( $p< $rp ){ // 子の開始 $p ++; $starter .= "<ul><li>"; }else { if( ($dp= $p-$rp) >0 ){ $p = $rp; $starter .= str_repeat('</li></ul>', $dp); } $starter .= '</li><li>'; } echo "$starter $row[1]: $row[2] :【$row[3]】"; } echo "\n". str_repeat('</li></ul>', $p) ; mysql_close($link); ?> </body> 上記の表示結果は、下記のようになります。 【表示結果】 2010年: .1. :【1】 6月: .1.2. :【1】 28日9: .1.2.3. :【1】 これを下記のような表示結果に変更する事は可能でしょうか? 2010年: .1. :【3】 6月: .1.2. :【2】 28日: .1.2.3. :【1】 やりたい事は、2010年には、それ以下に所属する合計を出したいと思いました(6月なども同様です)。 現在は、2010年そのものしか出せておりません。 pathフィールドの検索の仕方を考慮する必要があると思いましたが、どのようなSQL文を書けば良いか分からなかった為、 アドバイスいただける方がいらっしゃいましたら、ご教示の程よろしくお願いします。

  • PHP
  • 回答数1
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

命題がいまいちぴんとこないのですが、 単純に「自分を含む自分以下のデータの合計」ならこんな感じ SELECT id,name,path ,(SELECT count(*) FROM `sample_db` AS S2 WHERE S2.path LIKE CONCAT(S1.path,'%')) AS count FROM `sample_db` AS S1 これがstudentとどうからむのか仕様がはっきりしませんね

iroha_168
質問者

お礼

ご回答ありがとうございます。 ご教示いただいたソースを試した所、意図した動作になりました。 命題はご指摘の通り「自分を含む自分以下のデータの合計」となります。 ご指摘の言葉が思いつかず、上記のような分かりにくい質問になってしまい、申し訳ございません。 なお、student はとりあえず仮につけた名前で特に意図はありません。 あくまで「自分を含む自分以下のデータの合計」を取得する方法を知りたかっただけとなります。 このたびはどうもありがとうございました。 以上、よろしくお願いします。

関連するQ&A

  • 2つのテーブルからデータ取得

    いつもお世話になっております。 以下のようなテーブルがあります。 ---------- CREATE TABLE IF NOT EXISTS `students` ( `id` int(11) NOT NULL AUTO_INCREMENT, `student_number` bigint(20) DEFAULT NULL, `name` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ---------- CREATE TABLE IF NOT EXISTS `student_upload` ( `student_number` bigint(20) NOT NULL, `upload_id` int(11) NOT NULL ) ---------- データは以下のように登録されています。 students ---------- id|student_number|name 1 |11111     |いちろう 2 |22222     |じろう 3 |33333     |さぶろう student_upload ---------- student_number|upload_id 11111     |1 11111     |2 22222     |1 22222     |2 ---------- student_upload.upload_id=1 のデータを取得したいので 下記のようなSQL文を発行しているのですが、student_upload.upload_id=2 の データも取得されてしまいます。 select * from students s, student_upload up where up.upload_id=1 and up.student_number=s.student_number よろしくご教示お願いいたします。 <環境>  PHP:5.3.5  MySQL:5.0.7

    • ベストアンサー
    • MySQL
  • DBの値を基にliにulをネストしたリスト作成

    http://soft.fpso.jp/develop/php/entry_2790.htmlのようなphpでliにulをネストしたリストを作成したいと思います。 上記ページでは入れ子構造の配列を用意し実現していましたが、 下記のようなデータベースで同様の事を実現する方法がわからなかったので、 アドバイスいただける方がいらっしゃいましたら、ご教示の程よろしくお願いします。 なお、データベースのサンプルはあくまでサンプルのため、別途必要なフィールドなどがありましたら、その旨ご指摘いただければと思います。 【データベースのサンプル】 CREATE TABLE IF NOT EXISTS `sample_db` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(64) NOT NULL, `path` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `path` (`path`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ; INSERT INTO `sample_db` (`id`, `name`, `path`) VALUES (1, '2010年', '.1.'), (2, '6月', '.1.2.'), (3, '28日', '.1.2.3.'), (4, '12時', '.1.2.3.4.'), (5, '13時', '.1.2.3.5.'), (6, '29日', '.1.2.6.'), (7, '30日', '.1.2.7.'), (8, '7月', '.1.8.'), (9, '8月', '.1.9.'); 【ソースコードのサンプル】 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>タイトル</title> </head> <body> <?php $link = mysql_connect('localhost', 'データベースユーザ名', 'データベースパスワード名'); mysql_select_db('データベース名', $link); /* ▼▼▼ここから下の記述が分かりません。▼▼▼ */ $query = mysql_query("SELECT * FROM sample_db", $link); ?> <ul id="id_ul"> <?php while ($row = mysql_fetch_array($query)) { ?> <li class="class_li"><?php echo $row["name"]; ?></li> <?php } ?> </ul> /* ▲▲▲ここから上の記述が分かりません。▲▲▲ */ <?php mysql_close($link); ?> </body> </html> 以上、よろしくお願いします。

    • ベストアンサー
    • PHP
  • 年月の情報だけを基に階層構造を作る方法について

    下記のテーブルのような年月の情報だけを基に、添付ファイルのような階層構造を作成する事は可能でしょうか? CREATE TABLE IF NOT EXISTS `sample_db` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `year` varchar(255) NOT NULL, `month` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; INSERT INTO `sample_db` (`id`, `year`, `month`) VALUES (1, '10', '3'), (2, '10', '3'), (3, '10', '4'), (4, '11', '2'), (5, '11', '10'), (6, '12', '3'), (7, '12', ''), (8, '12', '5'), (9, '12', '5'); なお、http://www.makizou.com/archives/1662に記載されているpath情報をデータベースに持つ方法であれば、http://okwave.jp/qa/q6405985.htmlでご教示いただいた方法で実現できましたが、既存のデータベースで下記のような情報しか無い場合に実現可能か否か分からなかったので、 アドバイスいただける方がいらっしゃいましたら、ご教示の程よろしくお願いします。 以上、よろしくお願いします。

    • ベストアンサー
    • PHP
  • sql文について

    phpとmysqlの参考書を購入したのですがわからないことがあり 質問させてください。 参考書のサンプルとしてsample.sqlには以下の内容があります。 CREATE TABLE IF NOT EXISTS `author` ( `author_id` int(11) NOT NULL auto_increment, `author_name` varchar(255) NOT NULL default '', `author_name_kana` varchar(255) NOT NULL default '', `state` int(11) NOT NULL default '0', `description` text NOT NULL, PRIMARY KEY (`author_id`), KEY `author_name` (`author_name`), KEY `author_name_kana` (`author_name_kana`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; PRIMARY KEY (`author_id`),まではわかるのですがそれ以下の KEY ・・・とはなんのためにあり何をするのでしょうか? PRIMARY KEY・・・は主キーをauthor_idにするという設定かと 思うのですがKEY ・・・について意味がわかりません。 基本的すぎる事なのか参考書に説明がありませんでした^^; 詳しい方おりましたらわかりやすく教えて頂けますと幸いです。 宜しくお願い致します。

  • 取得値の複数使用

    $result = mysql_query("SELECT id, name FROM mytable"); while ($row = mysql_fetch_array($result, MYSQL_NUM)) { $id = mb_convert_encoding($row['id'] , "SJIS", "EUC"); $name = mb_convert_encoding($row['name'], "SJIS", "EUC"); echo $id.":".$name; } 一度DBより取得した値 $resultの中身を複数回使用したいのですが・・・。 毎回、DBにアクセスしないとダメですか?

    • 締切済み
    • PHP
  • sqliteへのデータ追加

    sql文で質問です。接続は1-29の表示を確認済み。 掲示板を作る練習をしているのですが、とりあえずpostなどのユーザーから受け取り値をdbに保存・表示する前に、自分で保存(カラムは左から順にid,name,sexになっていてidの1~29は埋まっている状態です。)・表示してみようと思いtest.dbのhumanテーブルに「データの追加」と表記している部分をテーブルに書き込み表示したいのですが、エラーは表示されないもののid30番にデータの追加ができておらず困っています。 データを追加する方法を教えてください。 <?php // 変数の初期化 $db = null; $sql = null; $res = null; $row = null; $db = new SQLite3("test.db"); // データの追加 $sql = 'INSERT INTO human( id, name, sex, ) VALUES ( 30, "吉川", "男", )'; // データの取得 $sql = 'SELECT * FROM human WHERE id BETWEEN 1 AND 50;'; $res = $db->query($sql); while( $row = $res->fetchArray() ) { echo '<ul>'.'<li>'. $row[0] . $row[1] .$row[2].'<li>'.'<ul>';} ?>

  • 取得データの置き換え方法

    SQL文で取得した情報(ID)を、文字列に変えてまた配列に戻したいのですがどのようにすればいいのかわかりません。 以下で、A.CODEで取得する値は1、2、3というようなIDになります。 この情報を、$siteに入れる際に、「1なら北海道」「2なら東北」というように入れ替えてやりたいのです。 直接情報を入れ替える方法や、別の配列に入れ替えてそれを$siteに入れる等、方法はあると思うのですが、どうしたらいいかわかりません。 よろしくお願いします。 $sql="select A.AREA_ID,A.NAME,A.CODE"; $line = mysql_num_rows($rs); $rs = mysql_query($sql,$db); for($j=0;$j<$line;$j++) { $row = mysql_fetch_row($rs); $site = "$row[1],$row[2],";

    • ベストアンサー
    • PHP
  • データベースから多次元連想配列でデータを取得できない

    PHP,MySQLともに初心者です いろんなサンプルプログラムを見て少しずつ進めているのですが、本3冊にネットで検索しても解決できないので・・・ function getSelect($field,$table,$where){ $query="select $field from $table $where;"; $result=$this->getResult($query); return $result; } $result=$db->getSelect("*","main","where myouji=$_POST[myouji]"); while($row = mysql_fetch_array($result[result])){ echo "$row[id]"; } こんな感じでmainテーブルからmyoujiに該当するrowを取得したのですが、 Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in とエラーが出てしまいます。 他のところで、 $result=$db->getSelect("*","main","where id=$_POST[id]"); $rows=mysql_fetch_array($result[result]); としたときはエラーなく行くのですが、上のような多次元連想配列(下の方はidを重複させてないので必ずrowが1つ・・・1次元連想配列?)になるとエラーになってしまいます。 これはどう修正すればいいのでしょうか。 たったこれ1行のつまづきで4時間くらいかかってます。 誰か助けてください

    • ベストアンサー
    • PHP
  • テーブルのデータをarray (array (***, ***)) の形式で取得したい

    id、氏名、年月日(date)、点数(tensu)の列を持つテーブルseiseki があります。 <?php $conn_id = mysql_connect("localhost","root","*****") or die('Error connecting to MySQL'); mysql_select_db('******',$conn_id); $query ="SELECT date,tensu from seiseki; $result = mysql_query($query,$conn_id) or die($query.'failed('.mysql_error().')'); $date = array(); $tensu = array(); while($row = mysql_fetch_array($result)){ $date[] = $row['date']; $tensu = $row['tensu']; } print_r($date); echo "<br/>\n";      ←15行目 print_r($tensu); echo "<br/>\n";      ←16行目 ?> これをブラウザで見ると、 Array ( [0] => 2009-05-01 [1] => 2009-06-07 [2] => 2009-07-24 ・・・・・・ ) Array ( [0] => 80 [1] => 75 [2] => 90 ・・・・・・・ ) となります。 15,16行目をコメントアウトして print_r($row[“date”],[“$tensu”]); とするとエラーになります。 array (array (2009-05-01, 80), array (2009-06-07, 75 ), array (2009-07-24 , 90)・・・・・・・ ); の形式でデータを取得するにはどのようにすれば良いでしょうか?

    • ベストアンサー
    • MySQL
  • SQLの効率化について

    下記のようなテーブルがあり、idの値を渡すと、下記のレコードを取得したいと思います。 1. 渡されたid=idのレコード 2. 渡されたid=parent_idのレコード 3. 渡されたid=parent_idのid=parent_idのレコード 【テーブル】 CREATE TABLE IF NOT EXISTS `tbl` ( `id` varchar(4) NOT NULL, `name` varchar(100) NOT NULL, `parent_id` varchar(4) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `tbl` (`id`, `name`, `parent_id`) VALUES ('0001', '親1', '0'), ('0002', '親2', '0'), ('0011', '子1-1', '0001'), ('0012', '子1-2', '0001'), ('0021', '子2-1', '0002'), ('0022', '子2-2', '0002'), ('0101', '子1-1-1', '0011'), ('0102', '子1-1-2', '0011'), ('0103', '子1-1-3', '0011'), ('0121', '子2-1-1', '0021'); 下記はそのソースとなり、やりたい事は出来ているのですが、SQLを3回実行しています。 多分2回目の$idに1回目の結果の$row["id"]、3回目の$id[$cnt]に2回目の結果の$s_idをセットすることが出来れば、1回のsql文で記述できるのではと思いましたが、 どのようなSQL文を書けば良いか分からなかった為、アドバイスいただける方がいらっしゃいましたら、ご教示の程よろしくお願いします。 【ソース】 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja" dir="ltr"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>title</title> </head> <body> <?php $link = mysql_connect('MySQL サーバ','ユーザー名','パスワード'); if (!$link) { die('接続できませんでした:' . mysql_error()); } if (!mysql_select_db('データベース名', $link)) { die ('データベースの選択失敗'); } $hairetsu = array(); $f_id = array(); $f_name = array(); $f_parent_id = array(); $s_id = array(); $s_name = array(); $s_parent_id = array(); $t_id = array(); $t_name = array(); $t_parent_id = array(); // 1回目 $query = mysql_query("SELECT * FROM tbl where id = '0001'", $link); if (!$query) { die(mysql_error()); } $row = mysql_fetch_array($query); $hairetsu["f_id"] = $row["id"]; $hairetsu["f_name"] = $row["name"]; $hairetsu["f_parent_id"] = $row["parent_id"]; $id = $row["id"]; // 2回目 $query = mysql_query("SELECT * FROM tbl where parent_id = $id", $link); if (!$query) { die(mysql_error()); } while ($row = mysql_fetch_array($query)) { array_push($s_id, $row["id"]); array_push($s_name, $row["name"]); array_push($s_parent_id, $row["parent_id"]); } $hairetsu["s_id"] = $s_id; $hairetsu["s_name"] = $s_name; $hairetsu["s_parent_id"] = $s_parent_id; $id = $hairetsu["s_id"]; // 3回目 for($cnt=0; $cnt<count($id); $cnt++) { $query = mysql_query("SELECT * FROM tbl where parent_id = $id[$cnt]", $link); if (!$query) { die(mysql_error()); } while ($row = mysql_fetch_array($query)) { array_push($t_id, $row["id"]); array_push($t_name, $row["name"]); array_push($t_parent_id, $row["parent_id"]); } } $hairetsu["t_id"] = $t_id; $hairetsu["t_name"] = $t_name; $hairetsu["t_parent_id"] = $t_parent_id; echo "<pre>"; var_dump($hairetsu); echo "</pre>"; mysql_close($link); ?> </body> </html> 以上、宜しくお願いします。

    • ベストアンサー
    • MySQL

専門家に質問してみよう