SQLで変数を代入してテーブルを繋げる方法とは?

このQ&Aのポイント
  • SQLを使用して、変数を計算して他のSQLに代入することは可能です。
  • データベースのテーブルを繋げるためには、JOIN文を使用する必要があります。
  • 具体的なクエリの組み合わせや変数の使い方についても解説しています。
回答を見る
  • ベストアンサー

SQLによって計算した変数を次のSQLに代入できますか?

user(テーブル) id | name | bango 1 | taro | 1001 2 | sato | 1012 3 | miho | 1027 4 | hiro | 1066 *idはautoincrement、bangoはユニークの値 mark(テーブル) id | check | bango 1 | 0 | 1001 2 | 1 | 1001 3 | 1 | 1001 4 | 0 | 1012 5 | 0 | 1012 6 | 1 | 1027 7 | 1 | 1027 8 | 0 | 1066 *idはautoincrement、checkは1か0、bangoはユニークの値 checkが1の確立が高い順にnameを一覧表示したいのですが、 うまく2つのテーブルを繋げることができません。 queryによって計算した変数を次のqueryに代入することはできるのでしょうか? 具体的には以下のような感じです。 bangoが1001のcheck=1の確立を出す場合 //bangoが1001の数 $test1 = mysql_query("select count(id) from mark where bango='1001';",$conn $row1 = mysql_fetch_array($test1, MYSQL_ASSOC); $totalct1 = $row1["count(id)"]; //bangoが1001かつcheckが1の数 $test2 = mysql_query("select count(id) from mark where bango='1001' and check='1' ;",$conn) $row2 = mysql_fetch_array($test2, MYSQL_ASSOC); $totalct2 = $row2["count(id)"]; //bangoが1001かつcheckが1の確立 if($totalct2==0){ $kakuritu = '0' ; } else{ $kakuritu = $totalct2 / $totalct1 * 100 ; } 上記の変数を下記のように入れ込むことはできないのでしょうか? $test3 = mysql_query("select name from user order by $kakuritu ;",$conn)

  • iiw2
  • お礼率70% (22/31)
  • MySQL
  • 回答数3
  • ありがとう数1

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

  • ベストアンサー
回答No.3

>次のように変えてみたのですがうまくいかないようです。 >これは構文的に問題があるのでしょうか? > >count(case when `check`=1 and `bango`=1001 then 1 else null end) as chk1, >また、下記の構文を試したのですが結果が同じでした。 > >SUM(IF(check=1 and bango=1001,1,0)) as chk1 「うまくいかない」とだけ書かれても、判断に困ります。具体的にどういうエラーメッセージやコードが出るのか提示してください。 使用している環境とともに、 (1)エラーになるなら、具体的なエラーの内容 (2)どういう結果を期待しているのに(期待とは違う)どういう結果になるのか といったことを示すのが、こういったサイトを利用する上での鉄則です。 また、「user表にあって、mark表にはない」といったケースは、どうしたいのでしょうか?それにより、「inner join」か「outer join」かという表の結合方法が変わってきます。 また、bango列のデータ型は何ですか? char(4)  ? dec(4)   ? int     ? その他? MySQLは、数字と文字のキャスト(型変換)を勝手にやってくれるというか、やってしまいます。これは、便利なようで、型変換のオーバーヘッドが発生します。 下記のSQLは、次の2点を変更しています。 (1)検索条件で、「bango=1001」を追加。 (2)「left join」を「inner join」に変更。  →「not null」の検索条件を追加すれば、「left [outer] join」で可能だが、要件が不明なため、このようにしておきました。 <SQL2>改訂版 select name, y.* from `user` as u -- left join inner join ( select *, chk1/ttl as rate1 from (select bango, count(case when `check`=1 then 1 else null end) as chk1, count(id) as ttl from `mark` -- bango=1001だけ ここから where `bango`='1001' -- bango=1001だけ ここまで group by bango ) as x ) as y on u.bango=y.bango order by y.rate1 desc,y.ttl desc,u.bango

iiw2
質問者

お礼

うまくいかないだけでは答えようがありませんね。すいませんでした。 改訂版でうまくいきました。 どうもありがとうございました。

その他の回答 (2)

回答No.2

#1です。 「やりたいことをSQLでやるには?」という回答をしましたが、質問の「変数の使い方とSQL」については未回答でしたので、追記します。 次の二つで、話がまったく違ってきます。 (1)SQL中の条件式や更新値、挿入値の変数での置換 例1 「?」の部分を置換 select * from t1 where c1=? update t1 set c2=? where c1=? (2)SQL中の表名、列名、条件式そのものなどの置換 例2 SQL中の任意の内容(xxxやyyy、zzz)を置換 select * from xxx where yyy update t1 set xxx=yyy where zzz 前者であれば、MySQL 5.0以降なら、prepareとexecuteの組み合わせで行えます。 後者であれば、SQL自体を文字列で組み立てるので、phpからの実行であれば、文字列を組み立てるだけのphpでの話しになります。

回答No.1

具体的なアドバイスをするには、情報が不足しています。 まず、MySQLのバージョンは? MySQL 4.1でサブクエリの実装など、MySQLは4.0まで、4.1、5.0以降で、多くの機能拡張や一部の仕様変更があります。 そのため具体的なSQLを提示しようとすると、バージョンにより違ってきます。 少し細かい話ですが、user表はbangoでユニークになるなら、わざわざauto_increment列を持つ必要はありません。 bango列のコード体系の変更の可能性で、auto_increment列を持っておいた方がいいかという話になりますが、複数のユニーク列を持つということは、重複チェックのオーバーヘッドが生じるということにもなります。 mark表は、「*idはautoincrement、checkは1か0、bangoはユニークの値」となっていますが、提示されたデータを見る限り、ユニークになるのはid列だけでは? 「check=1の出現率が同じ」の場合、どういう順序で得たいのでしょうか? まず、MySQL 4.1以降が前提ですが、次のSQLの結果を見てみてください。 もし、MySQL 4.0なら、サブクエリ部分を一時表(create temporary tableで定義)にするといったことで実装可能です。 次の優先順で、結果を返すようにしてみました。 (1)check=1の出現率が大きい順 (2)mark表の登録行数の多い順 (3)bangoの小さい順 クエリのネストは、別名で参照できるようにし、あえて深くしています。 <SQL例1> select *, chk1/ttl from (select bango, count(case when `check`=1 then 1 else null end) as chk1, count(id) as ttl from `mark` group by bango ) as x order by chk1/ttl desc,ttl desc,bango 次のSQL例が、「やりたいこと」ではないかと思います。 <SQL例2> select name, y.* from `user` as u left join ( select *, chk1/ttl as rate1 from (select bango, count(case when `check`=1 then 1 else null end) as chk1, count(id) as ttl from `mark` group by bango ) as x ) as y on u.bango=y.bango order by y.rate1 desc,y.ttl desc,u.bango

iiw2
質問者

補足

詳細なご説明ありがとうございます。 MYSQLのバージョンは5.0です。 bangoは出席番号のため重複する値がないという意味でユニークと書いてしまいました。 <SQL例2>の下記部分を count(case when `check`=1 then 1 else null end) as chk1, 次のように変えてみたのですがうまくいかないようです。 これは構文的に問題があるのでしょうか? count(case when `check`=1 and `bango`=1001 then 1 else null end) as chk1, また、下記の構文を試したのですが結果が同じでした。 SUM(IF(check=1 and bango=1001,1,0)) as chk1

関連するQ&A

  • 構文の省略について

    下記をもっと省略(短い構文で)して書きたいのですが、どのようなやり方があるでしょうか。 testというテーブルから指定したidのnameを取り出して並べたいだけなのですが、このような長々としたものしか思い浮かびませんでした。 <?php $n1 = 1; $n2 = 2; $n3 = 3; $rs1 = mysql_query("select * from test where id = '$n1';",$conn); $rec1 = mysql_fetch_array($rs1, MYSQL_ASSOC); echo $rec1['name']; echo <br>; $rs2 = mysql_query("select * from test where id = '$n2';"); $rec2 = mysql_fetch_array($rs2, MYSQL_ASSOC); echo $rec2['name']; echo <br>; $rs3 = mysql_query("select * from test where id = '$n3';"); $rec3 = mysql_fetch_array($rs3, MYSQL_ASSOC); echo $rec3['name']; mysql_free_result($rs1); mysql_free_result($rs2); mysql_free_result($rs3); mysql_close($conn); ?>

    • ベストアンサー
    • PHP
  • forで無限ループになっていないかどうか

    各アイテムの最新3件だけデータベースに残したいと思い、下記のようにしてみました。 動作を確認したところ問題なかったのですが、何か(無限ループする可能性があるなど)問題があるようでしたら、ご指摘いただけないでしょうか。 よろしくお願いいたします。 for ($num = 1; $num < 21; $num++){ // アイテムが20件ある場合 $sql = "SELECT COUNT(id) AS cnt FROM item where item_id=$num ;"; $res = mysql_query($sql, $conn) or die; $row = mysql_fetch_array($res, MYSQL_ASSOC); $count = $row["cnt"]; if($count<3){ // アイテムが3件より少なかったら何もしない } else{ $delete_count=$count-3; $sql = "delete from item where item_id=$num order by date limit $delete_count;"; $res = db_query($sql, $conn); } }

    • ベストアンサー
    • PHP
  • SQLのどこがおかしいでしょうか?

    PHP4、MySQLです。 for($i=1;$i<34;$i++){ $sql = "select count(group) as cnt".$i." "; $sql.= "from stock "; $sql.= "where group=".$i." "; //print "sql= ".$sql."<br>"; $result = mysql_query($sql,$db) or die("失敗しました".mysql_error ()); $Row = mysql_fetch_array($result, MYSQL_ASSOC); $cnt.$i = $Row['cnt".$i."']; } としています。どこがおかしいでしょうか? 教えてください。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • mysql_fetch_assoc()の非推奨

    phpを始めてまだ数ヶ月の初心者です。 (少々表現が変なところはお許し下さい。) ■やりたい事 phpである登録画面を作成しています。サーバーには スタッフのデーターが入っているテーブルがあります。 (1)DBに登録してあるスタッフの名前を全部引っ張り出す(mysql)。 (2)登録画面の入力項目の1つとして(登録スタッフ)があり、  そこを<select>で上記(1)から取り出したものを自動で表示したい。 ところが、mysql_fetch_assoc()について調べたら、非推奨などと載っていて (内容がよく理解できませんでしたが)どのように記述したら、将来困らない  コーディングとなりますか? <select name="register"> <?php $sql = "select count_ID, name from reserve"; $result = mysql_query($sql); while ($row = mysql_fetch_assoc($result)) { echo "<option value=\"".$row["count_ID"]."\">" .$row["name"]."</option>"; } ?> </select> 今からphpの知識を少しづつつけていくにあたり、非常に混乱して います。mysqlをそもそも学んでいてもしょうがないということでは ないですよね。本当に初心者なので、お手数ですがわかりやすい表現 でお願いします。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • sqlから多次元配列に要素を格納するコードの書き方

    現在sqlから読み込んだ要素をentries配列に格納しようと考えているのですが、 次のように書いてしまうと長く、複雑になってしまいます。 $res_result = mysql_query( "SELECT * from {$entry_title}", $link ); while( $entry_title = mysql_fetch_assoc( $res_result ) ){}; $res_result = mysql_query( "SELECT * from {$entry_url}", $link ); while( $entry_url = mysql_fetch_assoc( $res_result ) ){}; $res_result = mysql_query( "SELECT * from {$unix_time}", $link ); while( $unix_time = mysql_fetch_assoc( $res_result ) ){}; $res_result = mysql_query( "SELECT * from {$entry_count}", $link ); while( $entry_count = mysql_fetch_assoc( $res_result ) ){}; $entries[$i++] = array( "entry_title" => $entry_title, "entry_url" => $entry_url, "unix_time" => $unix_time, "entry_count" => $entry_count, ); もっと簡潔に書く方法はないでしょうか。 どなたかご教示のほど、どうかよろしくお願いします。

    • ベストアンサー
    • PHP
  • SQL文に変数を埋め込む場合の方法

    //config.php //$table = "TableName"; 1:require "config.php"; 2:$sql = "SELECT " . $fld . " AS genre, 3: COUNT(*) AS cnt FROM TableName GROUP BY " . 4:$fld; $res = mysql_query($sql, $conn) or die("Data抽出エラー"); 上記のソースを 2:$sql = "SELECT " . $fld . " AS genre, 3: COUNT(*) AS cnt FROM " . $table . " GROUP BY " . $fld; 4: $res = mysql_query($sql, $conn) or die("Data抽出エラー"); この様にして、config.phpより、テーブル名を変数として読み込みたいのですが、エラーになってしまいます。 3行目をどのように記述すればよいのでしょうか?

    • ベストアンサー
    • PHP
  • mySQLで結果が無いときの処理

    $sql = "select * from test "; $sql .= "where id='".$_POST["id"]."' and pwd='".$_POST["pwd"]."'"; $result = mysql_query($sql); while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { if($row){ $msg = "OK"; } } としていますが、NGのときってどういう風にしたらいいのでしょうか? 基本的なことですみませんが、教えてください。

    • ベストアンサー
    • PHP
  • mysqlからphpに表示ですべての項目を出したい

    phpとmysqlの勉強をしているのですが、出したい項目がでてきてくれません。 今mysqlでidとnameとpriceの項目を作っているのですが、以下だとどうしてもnameしか出てきてくれません。 どうすれば3つの項目がでてくれますでしょうか? よろしくお願いします。 <?     mysql_connect('localhost' , 'root' , '') or die(mysql_error());     mysql_select_db('db1'); mysql_query('SET NAMES UTF8'); $sql="SELECT * FROM syouhin"; $res=mysql_query($sql); $options=""; while($row = mysql_fetch_array($res,MYSQL_ASSOC)){ $options.="<input type=\"radio\" name=\"syouhin1\" value='{$row['id']}' checked>        {$row['name']}\n<br>"; } $select="{$options}</select>\n";     print $select; ?>

    • ベストアンサー
    • PHP
  • php 投票システム

    データベースと連動した投票システムを考えております。 phpとMySQLを使用したもので、対応するボタンを押すと1票投じられるというものです。 この仕組み自体は実現できたのですが、 ブラウザの更新ボタンを押すと、『情報を再送信する必要があります』と表示され、『はい』を押すと、自動的に1票投じられてしまいます。 スクリプトは以下のようになるのですが、上記のような不具合を修正するためにはどうすればよいのでしょうか。 アドバイス、具体的なソース、また、他の部分における修正すべき箇所など、ご指摘いただきたいと思います。 よろしくお願いいたします。 <?php echo "<table border=0>"; echo "<tr><td colspan=4 align=left><img src=logo-touhyou.gif></td></tr>"; echo "<tr><td><form method=post action="; echo $_SERVER["PHP_SELF"]; echo "><input type=hidden value=1 name=posi><input type=image src=logo-posi-s.gif border=0></form></td>"; echo "<td><form method=post action="; echo $_SERVER["PHP_SELF"]; echo "><input type=hidden value=1 name=deep><input type=image src=logo-deep-s.gif border=0></form></td></tr></table>"; $posi=$_POST["posi"]; $deep=$_POST["deep"]; if ($posi==1){ $server="mysql..jp"; $dbname="LA"; $user="LA"; $pass=""; $conn = mysql_connect($server,$user,$pass); $conndb = mysql_select_db($dbname); $sql="SELECT posi FROM test WHERE id =1 LIMIT 1"; $res=mysql_query($sql); while($row = mysql_fetch_assoc($res)) { $row_con=mb_convert_encoding($row["posi"], "shift_jis", "auto"); echo $row_con; echo "<br>"; $number1=1; $after=$row_con+$number1; echo $after; echo "<br>"; mysql_query("LOCK TABLES test WRITE"); $sql_1="UPDATE test SET posi='$after3' WHERE id =1 LIMIT 1"; $ins=mysql_query($sql); mysql_query("UNLOCK TABLES"); if ($ins_1){ echo "ポジティブ投票完了"; } $sql_2="SELECT posi FROM test WHERE id =1 LIMIT 1"; $res_2=mysql_query($sql_2); while($row_2 = mysql_fetch_assoc($res_2)) { $row_con_2=mb_convert_encoding($row_2["posi"], "shift_jis", "auto"); echo $row_con_2; } } mysql_close($conn); } if ($deep==1){ $server="mysql..jp"; $dbname="LA"; $user="LA"; $pass=""; $conn = mysql_connect($server,$user,$pass); $conndb = mysql_select_db($dbname); $sql2="SELECT deep FROM test WHERE id =2 LIMIT 1"; $res2=mysql_query($sql2); while($row2 = mysql_fetch_assoc($res2)) { $row_con2=mb_convert_encoding($row2["deep"], "shift_jis", "auto"); echo $row_con2; echo "<br>"; $number1=1; $after2=$row_con2+$number1; echo $after2; echo "<br>"; mysql_query("LOCK TABLES test WRITE"); $sql2_2="UPDATE test SET deep='$after2' WHERE id =2 LIMIT 1"; $ins2=mysql_query($sql2_2); mysql_query("UNLOCK TABLES"); if ($ins2){ echo "ディープ投票完了"; } $sql2_2="SELECT deep FROM test WHERE id =4 LIMIT 1"; $res2_2=mysql_query($sql2_2); while($row2_2 = mysql_fetch_assoc($res2_2)) { $row_con2_2=mb_convert_encoding($row2_2["deep"], "shift_jis", "auto"); echo $row_con2_2; } } mysql_close($conn); } ?>

    • ベストアンサー
    • PHP
  • mysql_query等でレコード数を変数に格納

    mysql> SELECT COUNT(id) AS rows FROM someTABLE WHERE name IN ( 'A','B','C' ) ; で +------+ | rows | +------+ | 9 | +------+ と出すことができます。 この rows の数「9」を php の変数に入れたいのです。 <?php // DB接続省略 $sql = "SELECT COUNT(id) AS rows FROM someTABLE WHERE name IN ( 'A','B','C' )" ; $result = mysql_query($sql, $conn); var_dump($sql."<br />"); echo ($result."--result"."<br/>"); $rows= mysql_num_rows($result); echo ($rows."--rows"."<br/>"); ?> として、ブラウザで確認すると string(80) "SELECT COUNT(id) AS rows FROM someTABLE WHERE name IN ( 'A','B','C' ) " Resource id #3--result 1--rows となって、 $rows に値’9’が入りません。$rows にレコード数を取得させるには、どうすれば良いでしょうか?

    • ベストアンサー
    • PHP