SQL文の書き方をご教授 | 分かりやすい解説あり

このQ&Aのポイント
  • SQL文の書き方についてご教授いたします。質問者様は、複数のチェックボックスで絞り込み検索を実装したいとのことですが、現在のSQL文に問題があり、二つ目の選択肢で絞り込めない状況にあるようです。こちらでは、正しいSQL文の書き方や絞り込み方法について詳しく解説いたします。
  • まず、現在のSQL文の問題点を確認しましょう。二つ目の選択肢を絞り込むためには、OR条件を用いる必要がありますが、現在のSQL文ではAND条件が重複してしまっているため、絞り込めない状況になっています。次に、正しいSQL文の書き方として、絞り込み条件をOR条件で結合する方法をご紹介いたします。
  • 絞り込み条件をOR条件で結合するためには、IN演算子を使用する方法があります。例えば、kidが1または2の場合を絞り込む場合、以下のようなSQL文を記述します。 SELECT * FROM テーブル名 WHERE kid IN (1, 2);
回答を見る
  • ベストアンサー

SQL文の書き方をご教授お願い致します。

<th>物件種別</th> <td> <input type="checkbox" name="kid[]" value="1" <?php if( $_REQUEST["kid"] == "1" ){ print( 'checked' ); } ?>/> 温泉 <input type="checkbox" name="kid[]" value="2" <?php if( $_REQUEST["kid"] == "2" ){ print( 'checked' ); } ?>/> キャンペーン <input type="checkbox" name="kid[]" value="3" <?php if( $_REQUEST["kid"] == "3" ){ print( 'checked' ); } ?>/> イベント <input type="checkbox" name="kid[]" value="4" <?php if( $_REQUEST["kid"] == "4" ){ print( 'checked' ); } ?>/> 特別室<br /> <input type="checkbox" name="kid[]" value="5" <?php if( $_REQUEST["kid"] == "5" ){ print( 'checked' ); } ?>/> 和室 <input type="checkbox" name="kid[]" value="6" <?php if( $_REQUEST["kid"] == "6" ){ print( 'checked' ); } ?>/> 喫煙室</td> </tr> <tr> //まずこのSQL文でt_hotelsのテーブルとt_hotel_kodawariを結合します $sql="SELECT t_hotels.id,t_hotels.hotel_name,t_hotels.price,t_hotels.address,t_hotel_kodawari.id,t_hotel_kodawari.kid FROM t_hotels JOIN t_hotel_kodawari USING(id) WHERE 1 "; テーブル t_hotel_kodawari id kid ------------ 1 1 1 2 1 4 2 1 2 5 3 2 4 3 4 6 5 2 5 3 6 1 7 2 テーブルt_hotels id hotel_name price address ----------------------------------------------------- 1 Aホテル 10000 栃木県・・・ 2 Bホテル 12000 栃木県・・・ 3 Cホテル 9000 千葉県・・・ 4 Dホテル 10000 千葉県・・・ 5 Eホテル 15000 愛知県・・・ 6 Fホテル 30000 東京都・・・ 7 Gホテル 40000 神奈川県・・・ テーブルt_hotels とt_hotel_kodawariをJOIN USINで結合して表示 id hotel_name price address id kid ------------------------------------------------------------------- 1 Aホテル 10000 栃木県・・・ 1 1 1 Aホテル 10000 栃木県・・・ 1 2 1 Aホテル 10000 栃木県・・・ 1 4 2 Bホテル 12000 栃木県・・・ 2 1 2 Bホテル 12000 栃木県・・・ 2 5 3 Cホテル 9000 千葉県・・・ 3 2 4 Dホテル 10000 千葉県・・・ 4 3 4 Dホテル 10000 千葉県・・・ 4 6 5 Eホテル 15000 愛知県・・・ 5 2 5 Eホテル 15000 愛知県・・・ 5 3 6 Fホテル 30000 東京都・・・ 6 1 7 Gホテル 40000 神奈川県 7 2 $condition = array(); //仮にkid1が一つ選択されたら まず if( !empty( $_POST["kid"] )){ for($i=0; $i<count($_REQUEST["kid"]); $i++) { $tmpKey = "kid".$i; $sql .= " and kid = :".$tmpKey; $condition[$tmpKey] = $_REQUEST["kid"][$i]; var_dump($sql); } } で絞り込まれSQL文が作られ、 var_dump($sql);でSQL文を表示させると string(184) "SELECT t_hotels.id,t_hotels.hotel_name,t_hotels.price,t_hotels.address,t_hotel_kodawari.id,t_hotel_kodawari.kid FROM t_hotels JOIN t_hotel_kodawari USING(id) WHERE 1 and kid = :kid0" の結果によって、 kid1を選択するとホテルA,B,Fが表示されます。 でkidがまずandで絞り込まれます。 ですが、もう二つ目選択すると string(184) "SELECT t_hotels.id,t_hotels.hotel_name,t_hotels.price,t_hotels.address,t_hotel_kodawari.id,t_hotel_kodawari.kid FROM t_hotels JOIN t_hotel_kodawari USING(id) WHERE 1 and kid = :kid0" string(200) "SELECT t_hotels.id,t_hotels.hotel_name,t_hotels.price,t_hotels.address,t_hotel_kodawari.id,t_hotel_kodawari.kid FROM t_hotels JOIN t_hotel_kodawari USING(id)「 WHERE 1 and kid = :kid0 and kid = :kid1"」 で ------------------------------------------- 二重にand で絞られてしまい何も出てきません。希望としては二回目の選択からkidはor条件にすれば仮にkid1,kid2ホテルA,B,C,E,F,Gと両方を含む表示を実現したいのですが、 実際はSQLの表記の方法をネットや本で調べたのですが、分からない状態です。ご教授いただけたらと思います。 なお、私の希望通りの方法ではなくても実現できれば大丈夫です。 どうかよろしくお願い致します。

  • MySQL
  • 回答数5
  • ありがとう数15

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

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

あ・・・$rowsの宣言がされてないですね while($row = $stmt->fetch(PDO::FETCH_ASSOC)){ $rows[]=$row; }; の直前に $rows=array(); としといた方がいいかもしれません。

sinto58167
質問者

お礼

出力できない理由がわかりました! 単純なミスでした。$rowで出力しなければならないのが$resultになっていました! お騒がせいたしました。 yambejp様には本当になんて言っていいのかわからないくらい感謝しております! 今回のような検索機能は実装できたのがはじめてなので、感無量です! 長きに渡って疑問がようやく解決されました。 yambejp様、そして他の方々も私のような素人の相談に乗っていただき本当にありがとうございました!

sinto58167
質問者

補足

まさに foreach((array) $rows as $row ){ にして$rows=array();も表記したら エラーが消えました。 エラーの行番号もyambejp様の仰る通りでした。 あと検索結果が項目意外、表示されないです。 カラムが合ってないのでしょうか? t_hotels id hotel_name price_min price_max address 1 HOTELA 10000 15000 栃木県・・・ 2 HOTELB 12000 20000 栃木県・・・ 3 HOTELC 9000 18000 千葉県・・・ 4 HOTELD 20000 25000 千葉県・・・ 5 HOTELE 15000 30000 愛知県・・・ 6 HOTELF 30000 35000 東京都・・・ 7 HOTELG 40000 43000 神奈川県・・・ t_hotel_kodawari hid kid 1 1 1 3 1 4 2 1 2 5 3 2 4 3 4 6 5 2 5 3 6 1 7 2 合ってると思うのですが。 以下、print_rの返す内容です。 SELECT t1.* FROM t_hotels as t1 INNER JOIN (SELECT DISTINCT hid FROM t_hotel_kodawari WHERE kid in (?,?)) as t2 ON t1.id=t2.hid WHERE 1 AND address LIKE ? AND price BETWEEN ? AND ? Array ( [0] => 1 [1] => 5 [2] => %千葉県% [3] => 6000 [4] => 10000 ) Array ( ) 原因は何が考えられますでしょうか? 何卒よろしくお願い致します。

その他の回答 (4)

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

>Warning: Invalid argument supplied for foreach() in に表示される行番号って foreach( $rows as $row ){ のところですか? $rowsが配列じゃない文字列や数値の時にでるエラーですね とりあえず foreach((array) $rows as $row ){ とすれば、なおるような気もしますが、 なぜここで$rowsが配列でなくなっているのかちょっとわかりません。 なにかタイプミスがあるのでしょうか?

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

じゃ、こんな感じで・・・ カラムの名称などは適当にあわせてください <?PHP //初期設定 //username,$password,$dbnameは適当に $dsn = 'mysql:host=localhost; dbname='.$dbname; $data=array(); $sql = "SELECT t1.* FROM t_hotels as t1 "; $flag=true; //kid絞り込み if(isset($_REQUEST["kid"]) and is_array($_REQUEST["kid"])){ $sql.="INNER JOIN (SELECT DISTINCT hid FROM t_hotel_kodawari WHERE kid in ("; $sql.=implode(",",array_fill(0,count($_REQUEST["kid"]), '?')); $sql.=")) as t2 ON t1.id=t2.hid "; $data=array_merge($data,$_REQUEST["kid"]); $flag=false; } //WHERE句作成 $sql.= "WHERE 1 "; //住所絞り込み if(isset($_REQUEST["address"]) and $_REQUEST["address"]!==""){ $sql.="AND address LIKE ? "; array_push($data,"%".$_REQUEST["address"]."%"); $flag=false; } //価格絞り込み if(isset($_REQUEST["price_min"]) and $_REQUEST["price_min"]!==""){ $price_min=str_replace(",","",$_REQUEST["price_min"]); }else{ $price_min=0; } if(isset($_REQUEST["price_max"]) and $_REQUEST["price_max"]!==""){ $price_max=str_replace(",","",$_REQUEST["price_max"]); }else{ $price_max=1000000; } if(isset($_REQUEST["price_min"]) or isset($_REQUEST["price_max"])){ $sql.="AND price BETWEEN ? AND ? "; array_push($data,$price_min,$price_max); $flag=false; } //なにもパラメータがないときは表示しない if($flag) $sql.="AND 0 ";; //参考 print $sql."<br>"; print_r($data); //実行 $pdo = new PDO($dsn,$username,$password); $stmt = $pdo->prepare( $sql); $stmt->execute($data); while($row = $stmt->fetch(PDO::FETCH_ASSOC)){ $rows[]=$row; }; print_r($rows);

sinto58167
質問者

補足

いつも教えていただき本当に感謝いたします。 あともう一息でできるのではと思っています。 ありがとうございます。 もしうまくいったらお礼をしたいくらいです。 まさかここまで教えてもらえるとは思ってもいませんでした。 いつも素人の質問でもうしわけありませんが、 このようなエラーが出てしまいます。 配列の出し方が問題だと思うのですが、どのようにプログラムを書けばいいのかわかりません。 一部前半の部分を省略したコードをさらしますので、 どう書けば良いのか教えていただきたいです。 ただ教えてくれるかどうかは全然自由なのでスルーしてもらっても大丈夫です。 Warning: Invalid argument supplied for foreach() in <body id="S03-10"> <div id="main"> <h1>ビジネスホテルの条件検索</h1> <form name="search_form" action="xxxxx.php" method="post" > <input type="hidden" name="cmd" value="search" /> <table> <tr> <th>物件種別</th> <td> <input type="checkbox" name="kid[]" value="1" <?php if( $_REQUEST["kid"] == "1" ){ print( 'checked' ); } ?>/> 温泉 <input type="checkbox" name="kid[]" value="2" <?php if( $_REQUEST["kid"] == "2" ){ print( 'checked' ); } ?>/> キャンペーン <input type="checkbox" name="kid[]" value="3" <?php if( $_REQUEST["kid"] == "3" ){ print( 'checked' ); } ?>/> イベント <input type="checkbox" name="kid[]" value="4" <?php if( $_REQUEST["kid"] == "4" ){ print( 'checked' ); } ?>/> 特別室<br /> <input type="checkbox" name="kid[]" value="5" <?php if( $_REQUEST["kid"] == "5" ){ print( 'checked' ); } ?>/> 和室 <input type="checkbox" name="kid[]" value="6" <?php if( $_REQUEST["kid"] == "6" ){ print( 'checked' ); } ?>/> 喫煙室</td> </tr> <tr> <th>価格帯</th> <td> <input type="text" name="price_min" value="<?php print( htmlspecialchars( $_REQUEST["price_min"] ,ENT_QUOTES ) ) ?>" size="8"> ~ <input type="text" name="price_max" value="<?php print( htmlspecialchars( $_REQUEST["price_max"] ,ENT_QUOTES ) ) ?>" size="8"><br /> </td> </tr> <tr> <th>住所</th> <td><input type="text" name="address" value="<?php print( htmlspecialchars( $_REQUEST["address"] ,ENT_QUOTES ) ) ?>" size="20"></td> </tr> </table> <input type="submit" value="検索" class="Btn-gray button"> </form> <p>&nbsp;</p> <?php //初期設定 //username,$password,$dbnameは適当に if( $_REQUEST["cmd"] == "search" ){ $dsn = 'mysql:host=localhost;dbname=hotel_reservation'; $username = 'root'; $password = 'xxxxxx'; $data=array(); $sql = "SELECT t1.* FROM t_hotels as t1 "; $flag=true; //kid絞り込み if(isset($_REQUEST["kid"]) and is_array($_REQUEST["kid"])){ $sql.="INNER JOIN (SELECT DISTINCT hid FROM t_hotel_kodawari WHERE kid in ("; $sql.=implode(",",array_fill(0,count($_REQUEST["kid"]), '?')); $sql.=")) as t2 ON t1.id=t2.hid "; $data=array_merge($data,$_REQUEST["kid"]); $flag=false; } //WHERE句作成 $sql.= "WHERE 1 "; //住所絞込み if(isset($_REQUEST["address"]) and $_REQUEST["address"]!==""){ $sql.="AND address LIKE ? "; array_push($data, "%" .$_REQUEST["address"]."%"); $flag=false; } //価格絞り込み if(isset($_REQUEST["price_min"]) and $_REQUEST["price_min"]!==""){ $price_min=str_replace(",","",$_REQUEST["price_min"]); }else{ $price_min=0; } if(isset($_REQUEST["price_max"]) and $_REQUEST["price_max"]!==""){ $price_max=str_replace(",","",$_REQUEST["price_max"]); }else{ $price_max=1000000; } if(isset($_REQUEST["price_min"]) or isset($_REQUEST["price_max"])){ $sql.="AND price BETWEEN ? AND ? "; array_push($data,$price_min,$price_max); $flag=false; } //なにもパラメータがないときは表示しない if($flag) $sql.="AND 0 ";; //参考 print $sql."<br>"; print_r($data); //実行 $pdo = new PDO($dsn,$username,$password); $stmt = $pdo->prepare($sql); $stmt->execute($data); while($row = $stmt->fetch(PDO::FETCH_ASSOC)){ $rows[]=$row; }; print_r($rows); ?> <table border="1"> <caption>検索結果</caption> <tr> <th></th> <th>ホテル名</th> <th>宿泊料金</th> <th>住所</th> </tr> <?php foreach( $rows as $row ){ ?> <tr> <td><img src="hotel/<?php print( htmlspecialchars( $result["id"], ENT_QUOTES )); ?>.png" /></td> <td><?php print( htmlspecialchars( $result["hotel_name"], ENT_QUOTES )); ?></td> <td>\<?php print( htmlspecialchars( number_format( $result["price_min"] ),ENT_QUOTES ) ); ?></td> <td> <?php print( htmlspecialchars( $result["address"], ENT_QUOTES ) ); ?> </td> </tr> <?php } } ?> </table> </div> </body> </html>

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

たとえばこんな感じ SELECT t1.* FROM t_hotels as t1 INNER JOIN (SELECT hid FROM t_hotel_kodawari WHERE kid in (1,3,4)) as t2 ON t1.id=t2.hid t_hotel_kodawariをkidの値で絞り込んでからINNER JOINするとよいでしょう PHPの処理的には $sql="SELECT t1.* FROM t_hotels as t1 "; if(isset($_REQUEST["kid"]) and is_array($_REQUEST["kid"])){ $sql.="INNER JOIN (SELECT hid FROM t_hotel_kodawari WHERE kid in (" $sql.=implode(",",array_fill(0,count($_REQUEST["kid"]), '?')) $sql.=") as t2 ON t1.id=t2.hid "; } のようにSQL文をつくっておき、あとからkidの値を?に当てはめればいいでしょう

sinto58167
質問者

補足

yambejp様、いつもご教授くださり大変感謝しております。ありがとうございます。 kidの部分まで絞り込んで値を入れていくSQL文はわかりませんでした。 私の読んでいる本には書いていないことばかりで理解することがかなり難しいです。 わたしにもっと理解力があればといつも思います。 Parse error: syntax error, unexpected '$sql' (T_VARIABLE) inという表示が出てしまいます。 原因がどこにあるのか力不足でわからない状態です。 私なりに考えたのですが、$conditionに何も無いからかもしれません。 もし別の原因で間違っていたら申し訳ありません。 もしよろしければ $condition[$tmpKey] = $_REQUEST["kid"][$i]; だとか if( !empty( $_REQUEST["address"] ) ){ $sql = $sql . " and ( address like :address ) "; $condition[":address"] = "%{$_REQUEST["address"]}%"; } というような感じで $conditionに値(プレースホルダでしょうか?)を入れるみたいなプログラムの書き方を教えてもらえないでしょうか? いつも申し訳ありません。 念のため他の受け手の方のプログラムさらしておきます。 今回も勉強させていただき、ありがとうございました。 if( !empty( $_REQUEST["price_min"] ) ){ $sql = $sql . " and price >= :price_min " ; $condition[":price_min"] = $_REQUEST["price_min"]; var_dump($sql); } if( !empty( $_REQUEST["price_max"] ) ){ $sql = $sql . " and price <= :price_max "; $condition[":price_max"] = $_REQUEST["price_max"]; } if( !empty( $_REQUEST["address"] ) ){ $sql = $sql . " and ( address like :address ) "; $condition[":address"] = "%{$_REQUEST["address"]}%"; } $statement = $pdo->prepare( $sql ); $statement->execute( $condition ); $results = $statement->fetchAll();

  • t_ohta
  • ベストアンサー率38% (5066/13238)
回答No.1

$sql .= " and kid = :".$tmpKey; を $sql .= " or kid = :".$tmpKey; にするだけでは?

sinto58167
質問者

お礼

t_ohta様、今回もアドバイス感謝いたします。 誠にありがとうございます。 orに変更したのですが、重複して表示されていて上からAホテルが3つ、Bホテル2つが、Cは1つ、 Dが2つ、Eが2つ、Fが1、Gが1つ縦に並んだ状態になってしまいます。 重複表示しないようにしたいのですが、なかなかうまくいきません。 HTMLの表示のさせかたか、MySQL並べ方が良くないのでしょうか?要因はどこにあるかわからない状態です。 質問ばかりで申し訳ありません。

関連するQ&A

  • PDOを使ったSQL文の入力方法

    私のやりたいことはSQL文の実行なのですが、PDOを使った操作になります。 どうかご教授お願い致します。 <th>価格帯</th> <td> <select name="price_min"> <option value="1" selected="selected">下限なし</option> <option value="10000000">1000万</option> <option value="15000000">1500万</option> <option value="20000000">2000万</option> 以下略 <th>愛知県 - 名古屋市</th> <td> <input type="checkbox" name="chiiki_id[]" value="1" <?php if (isset($_REQUEST['chiiki_id']) and in_array('1',$_REQUEST['chiiki_id'])) print 'checked'; ?>/> 中村区 <input type="checkbox" name="chiiki_id[]" value="2" <?php if (isset($_REQUEST['chiiki_id']) and in_array('2',$_REQUEST['chiiki_id'])) print 'checked'; ?>/> 西区 <input type="checkbox" name="chiiki_id[]" value="3" <?php if (isset($_REQUEST['chiiki_id']) and in_array('3',$_REQUEST['chiiki_id'])) print 'checked'; ?>/> 昭和区 <input type="checkbox" name="chiiki_id[]" value="4" <?php if (isset($_REQUEST['chiiki_id']) and in_array('4',$_REQUEST['chiiki_id'])) print 'checked'; ?>/> 港区 </td> <th>こだわり条件</th> <td> <input type="checkbox" name="kid[]" value="1" <?php if (isset($_REQUEST['kid']) and in_array('1',$_REQUEST['kid1'])) print 'checked'; ?>/> 新築 <input type="checkbox" name="kid[]" value="2" <?php if (isset($_REQUEST['kid']) and in_array('2',$_REQUEST['kid2'])) print 'checked'; ?>/> 南向き <input type="checkbox" name="kid[]" value="3" <?php if (isset($_REQUEST['kid']) and in_array('3',$_REQUEST['kid3'])) print 'checked'; ?>/> セキュリティ充実 <input type="checkbox" name="kid[]" value="4" <?php if (isset($_REQUEST['kid']) and in_array('4',$_REQUEST['kid4'])) print 'checked'; ?>/> 市街地が近い<br /> <input type="checkbox" name="kid[]" value="5" <?php if (isset($_REQUEST['kid']) and in_array('5',$_REQUEST['kid5'])) print 'checked'; ?>/> 内装リフォーム <input type="checkbox" name="kid[]" value="6" <?php if (isset($_REQUEST['kid']) and in_array('6',$_REQUEST['kid6'])) print 'checked'; ?>/> システムキッチン <input type="checkbox" name="kid[]" value="7" <?php if (isset($_REQUEST['kid']) and in_array('7',$_REQUEST['kid7'])) print 'checked'; ?>/> ペット可</td> </tr> </table> <input type="submit" value="検索" class="Btn-gray button"> </form> $sql = 'SELECT DISTINCT * FROM bukken'; //名古屋の地域checkbox if(isset($_POST['chiiki_id'])and is_array($_POST['chiiki_id'])){ $ary = array_filter($_POST['chiiki_id'], function($v) {return is_numeric($v);}); $sqlA = 'id IN (SELECT chiid FROM chiiki WHERE chiiki_id IN ('.implode(',', $ary).'))'; }else{ //print '地域がチェックされてません'; $sqlA = ' 1 '; } //kid絞り込み if(isset($_POST['kid'])and is_array($_POST['kid'])){ $ary = array_filter($_POST['kid'], function($v) {return is_numeric($v);}); $sqlK1 = 'id IN (SELECT fid FROM fudou_kodawari2 WHERE kid IN ('.implode(',', $ary).'))'; }else{ //print '<br />こだわりがチェックされてません'; $sqlK1 = ' 1 '; } のようなフォームからチェックされた値のkidのところを絞った条件で表示させたいです。下記のPHPで値を受けてSQL文をMySQLに接続してSQLを実行するのですが、中々出来ません。 そして テーブルがbukkenとkodawariがあります。 bukken id bukken_name chiiki_id address price_min price_max     station 1 名駅MID    1 愛知県名古屋市中村区 40770000 55100000 名古屋駅 2 プレサン浄心 2 愛知県名古屋市西区城西 30800000 40001000 浄心駅 3 アネシア八事 3 愛知県名古屋市昭和区 50000000 62510000 八事日赤 4 アメニ港明 4 愛知県名古屋市港区港明 25000000 35000000 港区役所駅 5 ユーハウス上飯田 15 愛知県名古屋市北区 32000000 43330000 上飯田駅 6 ローレル葵 6 愛知県名古屋市東区葵x 30000000 46000000 高岡駅 7 ライオンズ2 愛知県名古屋市西区山木 35000000 55000000 上小田井駅 8 ポレスター名西 2 愛知県名古屋市西区名西 28000000 38000000 浄心駅 fudou_kodawari2 fid kid 1 1 1 2 1 3 2 1 3 2 3 3 3 4 4 3 5 4 6 4 7 1 8 1 8 2 8 4 このようなテーブルでSELECT DISTINCT * FROM bukken WHERE (id IN (SELECT fid FROM fudou_kodawari2 WHERE kid IN (1,2,3)))と言うSQL文を入力すると id bukken_name chiiki_id address price_min price_max     station 1 名駅MID    1 愛知県名古屋市中村区 40770000 55100000 名古屋駅 2 プレサン浄心 2 愛知県名古屋市西区城西 30800000 40001000 浄心駅 3 アネシア八事 3 愛知県名古屋市昭和区 50000000 62510000 八事日赤 4 アメニ港明 4 愛知県名古屋市港区港明 25000000 35000000 港区役所駅 7 ライオンズ2 愛知県名古屋市西区山木 35000000 55000000 上小田井駅 8 ポレスター名西 2 愛知県名古屋市西区 28000000 38000000 浄心駅 kidの条件 1の場合  fidが 1,2,7,8 2の場合 fidが 1,3,8 3の場合  fidが 1,3,4 なので  1,2,3,4,7,8 という結果が表示されますが、1,2,3の全てに一致する条件しか表示できないようにする(結果が1になる)にはどのようなSQL文を入力すれば良いのでしょうか?

    • ベストアンサー
    • PHP
  • PHPでMySQLを使った検索のプログラム2

    まだ解決できないので、大変恐縮ですがご教授お願いします。 どうかよろしくお願いいたします。 数人にご教授いただいき、チェックボックスの選択には一つのkid(kodawari_keyの略)に対して2複数の値をもっているホテルを表示させるにはデータベースのtableを複数に分けて紐付けする必要があるとアドバイスをいただき、教えて頂いたとおりtableをホテル用とチェックボックス用とチェックボックスのid用とに分けて、SQL文で紐付けしたつもりだったのですが、チェックボックスをチェックしてから検索ボタンを押すと Fatal error: Call to a member function execute() on a non-object in C:\xampp\htdocs\koredake\xxxxx\xxxxxxx.php on line 97 のようなエラーが出てしまいます。 このことから紐付けのSQL文が間違っているのではと思うのですが、正解がわかりません。 どなたか教えていただけたらと思っております。 //MySQLの部分 教えていただいた部分で大変恐縮です。 //ホテルの基本情報 CREATE TABLE t_hotels(id int not null primary key,name varchar(100) not null,price_min int not null,price_max int not null,address varchar(100) not null); INSERT INTO t_hotels VALUES(1,'HOTEL A',5000,10000,'栃木県・・・'), (2,'HOTEL B',5000,12000,'栃木県・・・'), //こだわり情報 CREATE TABLE t_kodawari_key(id int not null primary key,name varchar(20)); INSERT INTO t_kodawari_key VALUES(1,'温泉'),(2,'ランチ'),(3,' ディナー'); //ホテルごとのこだわり CREATE TABLE t_hotel_kodawari(hid int not null,kid int not null,unique key(hid,kid)); INSERT INTO t_hotel_kodawari VALUES(1,1),(1,2),(1,3),(2,1),(3,2),(3,3),(4,3); //温泉かランチにこだわりがあるところ SELECT hid,t3.name,t3.price_min,t3.price_max,GROUP_CONCAT(t2.name) as kodawari,t3.address //温泉かランチかディナーのうち2つ以上にこだわりがあるところ SELECT hid,t3.name,t3.price_min,t3.price_max,GROUP_CONCAT(t2.name) as kodawari,t3.address //PHP部分 前半省略 <h1>ビジネスホテルの条件検索</h1> <form name="search_form" action="zenzen16.php" method="post" > <input type="hidden" name="cmd" value="search" /> <table> <tr> <th>物件種別</th> <td> <input type="checkbox" name="kid[]" value="1" <?php if( $_REQUEST["kid"] == "1" ){ print( 'checked' ); } ?>/> 温泉 <input type="checkbox" name="kid[]" value="2" <?php if( $_REQUEST["kid"] == "2" ){ print( 'checked' ); } ?>/> ランチ<br /> <input type="checkbox" name="kid[]" value="3" <?php if( $_REQUEST["kid"] == "3" ){ print( 'checked' ); } ?>/> ディナー <input type="checkbox" name="kid[]" value="4" <?php if( $_REQUEST["kid"] == "4" ){ print( 'checked' ); } ?>/> 駐車場</td> </tr> <tr> <th>価格帯</th> <td> <input type="text" name="price_min" value="<?php print( htmlspecialchars( $_REQUEST["price_min"] ,ENT_QUOTES ) ) ?>" size="8"> ~ <input type="text" name="price_max" value="<?php print( htmlspecialchars( $_REQUEST["price_max"] ,ENT_QUOTES ) ) ?>" size="8"><br /> </td> </tr> <tr> <th>住所</th> <td><input type="text" name="address" value="<?php print( htmlspecialchars( $_REQUEST["address"] ,ENT_QUOTES ) ) ?>" size="20"></td> </tr> </table> <input type="submit" value="検索" class="Btn-gray button"> </form> <p>&nbsp;</p> <?php if( $_REQUEST["cmd"] == "search" ){ $pdo = new PDO("mysql:host=localhost; dbname=hotel_reservation; charset=utf8", "koredake", "koredake123", array( PDO::ATTR_EMULATE_PREPARES => false ) ); $sql = "select * from t_hotels where 1 = 1 "; $condition = array(); //この部分が特に自信が無いです。 if( !empty( $_POST["kid"] )){ $sql = $sql . " left outer join kid on t_hotels.hid = kid.hid"; } if( !empty( $_REQUEST["price_min"] ) ){ $sql = $sql . " and price >= :price_min "; $condition[":price_min"] = $_REQUEST["price_min"]; } if( !empty( $_REQUEST["price_max"] ) ){ $sql = $sql . " and price <= :price_max "; $condition[":price_max"] = $_REQUEST["price_max"]; } if( !empty( $_REQUEST["address"] ) ){ $sql = $sql . " and ( address like :address ) "; $condition[":address"] = "%{$_REQUEST["address"]}%"; } $statement = $pdo->prepare( $sql ); $statement->execute( $condition ); $results = $statement->fetchAll(); ?> <table border="1"> <caption>検索結果</caption> <tr> <th></th> <th>ホテル名</th> <th>宿泊料金</th> <th>住所</th> </tr> <?php foreach( $results as $result ){ ?> <tr> <td><img src="hotel/<?php print( htmlspecialchars( $result["id"], ENT_QUOTES )); ?>.png" /></td> <td><?php print( htmlspecialchars( $result["hotel_name"], ENT_QUOTES )); ?></td> <td>\<?php print( htmlspecialchars( number_format( $result["price"] ),ENT_QUOTES ) ); ?></td> <td> <?php print( htmlspecialchars( $result["address"], ENT_QUOTES ) ); ?> </td> </tr> <?php } } ?> </table> </div>

    • ベストアンサー
    • MySQL
  • MySQLの質問です。2

    お世話になります。 以前質問させていただいたのですがごちゃごちゃになってしまったので項目など見直してもっと単純な作りにしたいと思います。 MySQLを使ったWEBアプリを作っているのですが、特にこだわりのcheckboxと地域のcheckboxで分けてフォームからPHPのプログラムで受けて展開させる方法がわかりません。 どなたかご教授いただけたらと思っております。 テーブルに関しては賛否両論ですが、まずは3つでやってみたいと思います。 1つのほうが簡単そうなのですが、せっかく作ったので。 SQL文の間違いなのはわかっているのですがどうしてもわかりません。 何卒よろしくお願い致します。 下記のようなフォームにしたいと思っております。 <h1>マンション物件の条件検索</h1> <form name="search_form" action="mansion.php" method="post" > <input type="hidden" name="cmd" value="search" /> <table> <tr> <th>価格帯</th> <td> <select name="price_min"> <option value="1" selected="selected">下限なし</option> <option value="10000000">1000万</option> <option value="15000000">1500万</option> 略 </select> ~ <select name="price_max"> <option value="999999999999" selected="selected">上限なし</option> <option value="10000000">1000万</option> 略 </select> </td> </tr> <tr> <th>愛知県 - 名古屋市</th> <td> <td> <input type="checkbox" name="chiiki_id[]" value="1" <?php if( $_REQUEST["chiiki_id"] == "1" ){ print( 'checked' ); } ?>/> 中村区 <input type="checkbox" name="chiiki_id[]" value="2" <?php if( $_REQUEST["chiiki_id"] == "2" ){ print( 'checked' ); } ?>/> 西区 略 </tr> <tr> <th>愛知県 - その他の地域</th> <td> <input type="checkbox" name="chiiki_id[]" value="1" <?php if( $_REQUEST["chiiki_id"] == "1" ){ print( 'checked' ); } ?>/> 尾張 <input type="checkbox" name="chiiki_id[]" value="2" <?php if( $_REQUEST["chiiki_id"] == "2" ){ print( 'checked' ); } ?>/> 三河 </td> </tr> <th>こだわり条件</th> <td> <input type="checkbox" name="kid[]" value="1" <?php if( $_REQUEST["kid"] == "1" ){ print( 'checked' ); } ?>/> 新築 <input type="checkbox" name="kid[]" value="2" <?php if( $_REQUEST["kid"] == "2" ){ print( 'checked' ); } ?>/> 南向き <input type="checkbox" name="kid[]" value="3" <?php if( $_REQUEST["kid"] == "3" ){ print( 'checked' ); } ?>/> セキュリティ充実 </td> </tr> </table> <input type="submit" value="検索" class="Btn-gray button"> </form> <p>&nbsp;</p> <?php //初期設定 //username,$password,$dbnameは適当に if( $_REQUEST["cmd"] == "search" ){ $dsn = 'mysql:host=localhost;dbname=fudousan'; $username = 'xxxxx'; $password = 'xxxxxxx'; $data=array(); $sql = "SELECT t1.* FROM bukken as t1 "; $flag=true; //kid絞り込み if(isset($_REQUEST["kid"]) and is_array($_REQUEST["kid"])){ $sql.="INNER JOIN (SELECT DISTINCT fid FROM fdou_kodawari WHERE kid in ("; $sql.=implode(",",array_fill(0,count($_REQUEST["kid"]), '?')); $sql.=")) as t2 ON t1.id=t2.fid "; $data=array_merge($data,$_REQUEST["kid"]); $flag=false; } //WHERE句作成 $sql.= "WHERE 1 "; //名古屋の地域checkbox $sql = "SELECT t1.* FROM bukken as t1 "; if(isset($_REQUEST["chiiki_id"]) and is_array($_REQUEST["chiiki_id"])){ $sql.="INNER JOIN (SELECT DISTINCT chiid FROM chiiki WHERE chiiki_id in ("; $sql.=implode(",",array_fill(0,count($_REQUEST["chiiki_id"]), '?')); $sql.=")) as t2 ON t1.id=t2.chiid "; $data=array_merge($data,$_REQUEST["chiiki_id"]); $flag=false; } //WHERE句作成 $sql.= "WHERE 1 "; //価格絞り込み if(isset($_REQUEST["price_min"]) and $_REQUEST["price_min"]!==""){ $price_min=str_replace(",","",$_REQUEST["price_min"]); }else{ $price_min=0; } if(isset($_REQUEST["price_max"]) and $_REQUEST["price_max"]!==""){ $price_max=str_replace(",","",$_REQUEST["price_max"]); }else{ $price_max=100000000; } if(isset($_REQUEST["price_min"]) or isset($_REQUEST["price_max"])){ $sql.="AND price_min BETWEEN ? AND ? "; array_push($data,$price_min,$price_max); $flag=false; } //実行 $pdo = new PDO($dsn,$username,$password); $stmt = $pdo->prepare($sql); $stmt->execute($data); $rows=array( 以下省略 使っている3つのテーブルです。 bukken id、 bukken_name、 address 、price_min、 price_max、 station 1 名駅MID 愛知県名古屋市中村区 40770000、 55100000 名古屋駅 2 プレサン浄心 愛知県名古屋市西区 30800000、 40001000 浄心駅 3 アネシア八事 愛知県名古屋市昭和区50000000、 62510000 八事日赤 4 アメニ港明 愛知県名古屋市港区 25000000、 35000000 港区役所駅 5 ユーハウ上飯田 愛知県名古屋市北区 32000000、 43330000 上飯田駅 6 ローレル葵 愛知県名古屋市東区 30000000、 46000000 高岳駅 7 ライオンズ上小田井 愛知県名古屋市西区 35000000、 55000000 上小田井駅 8 ポレスターセントラル名西 愛知県名古屋市西区 28000000、 38000000 浄心駅 chiikiテーブル chiid chiiki_id 1 1 2 2 3 3 4 4 5 15 6 6 7 2 fudou_kodawariテーブル fid kid 1 1 1 2 1 3

  • PHPでMySQLを使った検索のプログラム

    「たったコレだけでPHPプログラミングが理解できる本」を参考にPHPでプログラムを書いていまして、 ビジネスホテルの検索機能をチェックボックス機能を余分につけて検索できないか試したのですが、 チェックボックスにチェックを入れると全く検索できず他のテキストボックスに入力するだけなら検索できます。 なんとかチェックボックスを有効にできないかいろいろなサイトを調べたり本を読んだりしましたが解決策が見つかりません。 いろいろな機能に対応できるようなプログラムを組みたいと思ったのでかなりの初心者で大変恐縮ですが、どなたかご教授お願いできないかと思っております。 あと参考になるサイトがございましたら、教えていただきたいと思っております。 何卒よろしくお願い致します。 前半省略 <form name="search_form" action="" method="post" > <input type="hidden" name="cmd" value="search" /> <table> <tr> <th>物件種別</th> <td> <input type="checkbox" name="kodawari_key[]" value="温泉" <?php if( $_REQUEST["kodawari_key"] == "温泉" ){ print( 'checked' ); } ?>/> 温泉 <input type="checkbox" name="kodawari_key[]" value="ランチ" <?php if( $_REQUEST["kodawari_key"] == "ランチ" ){ print( 'checked' ); } ?>/> ランチ<br /> <input type="checkbox" name="kodawari_key[]" value="ディナー" <?php if( $_REQUEST["kodawari_key"] == "ディナー" ){ print( 'checked' ); } ?>/> ディナー</td> </tr> <tr> <th>価格帯</th> <td> <input type="text" name="price_min" value="<?php print( htmlspecialchars( $_REQUEST["price_min"] ,ENT_QUOTES ) ) ?>" size="8"> ~ <input type="text" name="price_max" value="<?php print( htmlspecialchars( $_REQUEST["price_max"] ,ENT_QUOTES ) ) ?>" size="8"><br /> </td> </tr> <tr> <th>住所</th> <td><input type="text" name="address" value="<?php print( htmlspecialchars( $_REQUEST["address"] ,ENT_QUOTES ) ) ?>" size="20"></td> </tr> </table> <input type="submit" value="検索" class="Btn-gray button"> </form> <p>&nbsp;</p> <?php if( $_REQUEST["cmd"] == "search" ){ $pdo = new PDO("mysql:host=localhost; dbname=hotel_reservation; charset=utf8", "koredake", "koredake123", array( PDO::ATTR_EMULATE_PREPARES => false ) ); $sql = "select * from hotels where 1 = 1 "; $condition = array(); if( !empty( $_POST["kodawari_key"] )){ $sql = $sql . " and kodawari_key = :kodawari_key"; $condition["kodawari_key"] = $_REQUEST["kodawari_key"]; } if( !empty( $_REQUEST["price_min"] ) ){ $sql = $sql . " and price >= :price_min "; $condition[":price_min"] = $_REQUEST["price_min"]; } if( !empty( $_REQUEST["price_max"] ) ){ $sql = $sql . " and price <= :price_max "; $condition[":price_max"] = $_REQUEST["price_max"]; } if( !empty( $_REQUEST["address"] ) ){ $sql = $sql . " and ( pref like :pref or city like :city or address like :address ) "; $condition[":pref"] = "%{$_REQUEST["address"]}%"; $condition[":city"] = "%{$_REQUEST["address"]}%"; $condition[":address"] = "%{$_REQUEST["address"]}%"; } $statement = $pdo->prepare( $sql ); $statement->execute( $condition ); $results = $statement->fetchAll(); ?> <table border="1"> <caption>検索結果</caption> <tr> <th></th> <th>ホテル名</th> <th>宿泊料金</th> <th>住所</th> </tr> <?php foreach( $results as $result ){ ?> <tr> <td><img src="hotel/<?php print( htmlspecialchars( $result["id"], ENT_QUOTES )); ?>.png" /></td> <td><?php print( htmlspecialchars( $result["hotel_name"], ENT_QUOTES )); ?></td> <td>\<?php print( htmlspecialchars( number_format( $result["price"] ),ENT_QUOTES ) ); ?></td> <td> <?php print( htmlspecialchars( $result["pref"], ENT_QUOTES ) ); ?> <?php print( htmlspecialchars( $result["city"], ENT_QUOTES ) ); ?> <?php print( htmlspecialchars( $result["address"], ENT_QUOTES ) ); ?> </td> </tr> <?php } } ?> </table> </div> </body> </html>

    • ベストアンサー
    • MySQL
  • SQL文について質問させて頂きます。

    いつもお世話になっております。いろいろSQL文の本を読んだのですがわからないので今回もよろしく お願い致します。 SELECT DISTINCT * FROM bukken WHERE (id IN (SELECT fid FROM fudou_kodawari WHERE kid IN (1,4))) というSQL文があるのですが、これだと1,4が1つでも含まれるリストが出てくるのですが1,4が完全に一致しないと出てこないようにするにはどのようにSQL文を変更すれば良いのでしょうか? 何卒よろしくお願い致します。

  • 2つのSQL文で結果に差違が発生する

    私の知識ではお手上げのため、ご教授願いたいのですが、 下記のようなテーブルが仮にあったとして、レコードがそれぞれいくつか入っています。 【itemsテーブル】   id・・・・・連番   cat_id・・・category.id   price ・・・価格   max_num ・・セット数   date・・・・発売日 【categioryテーブル】   id・・・・・連番   cat_name・・カテゴリ名 【orderテーブル】   id・・・・・連番   item_id ・・items.id   paid_price・支払価格 以下の2つのSQL文を実行させた場合、「total_price」の値に違いは発生しますか? 【SQL文 A】----------------------------- SELECT items.cat_id, `category`.`cat_name`, SUM(`items`.`price` * `items`.`max_num`) AS `total_price`, SUM(IF(`order`.`paid_price` > 0, `order`.`paid_price`, 0)) AS `total_paid`, SUM(IF(`order`.`paid_price` = 0 , `items`.`price`, 0)) AS `not_payment` FROM `items` INNER JOIN `category` ON (`items`.`cat_id` = `category`.`id`) INNER JOIN `order` ON (`items`.`id` = `order`.`item_id`) WHERE DATE_FORMAT(`items`.`date`, '%Y%m') = 201511 GROUP BY `items`.`cat_id` ORDER BY `items`.`cat_id` ASC ------------------------------------ 【SQL文 B】----------------------------- SELECT items.cat_id, `category`.`cat_name`, SUM(`items`.`price` * `items`.`max_num`) AS `total_price` FROM `items` INNER JOIN `category` ON (`items`.`cat_id` = `category`.`id`) WHERE AND DATE_FORMAT(`items`.`date`, '%Y%m') = 201511 GROUP BY `items`.`cat_id` ORDER BY `items`.`cat_id` ASC ------------------------------------ こちらで上記と同じようなSQL文を実行すると、Bで出てほしい値がAでは出てこないのです。 Aの場合は「WHERE DATE_FORMAT(`items`.`date`, '%Y%m') = 201511」が抽出条件として実行されていないような感じです。 すべてのレコードの「SUM(`items`.`price` * `items`.`max_num`) AS `total_price`」が計算されています。 Bだけで実行すればちゃんとほしい値が返ってきます。 何か間違っていますか?

    • ベストアンサー
    • MySQL
  • SQL文の処理を関数化したいです

    SQL文をユーザー定義関数でまとめたいのですが、うまくいきません。 以下の処理を全てfunction search() { }の中に入れるのは間違っていますか? 関数名はsearchとしました。 try { $sql = 'SELECT product.id, name, price, img, status, stock FROM product JOIN item_stock ON product.id = item_stock.stock_id WHERE status = 1'; $stmt = $dbh->prepare($sql); $stmt->execute(); $result = $stmt->fetchALL(); $err_msg[] = ($keyword . 'を含む商品は見つかりませんでした。'); } catch (PDOException $e) { $err_msg[] = '商品を取得できませんでした。'; }

    • ベストアンサー
    • PHP
  • SQLがわからないです

    kid | id | name | day | tday | 1 | 1 | 松 | 25 | 1 | 2 | 谷  | 15 | このようなデータがあったとして、それぞれのMAX(day)を出力する場合どうしたらいいでしょうか?? $sql2 = 'SELECT kid,id,name,MAX(day),tday FROM em WHERE kid='.$_SESSION["kid"].'' ; これだと松さんのデータしか出力されないし、MAXを外すと、例えば松さんのデータが二個あり出力した場合、松(25)松(18)谷(15)と出力されてしまいます。 希望は 松(25)谷(15) それぞれの最大値です。

    • ベストアンサー
    • MySQL
  • 全パターンを出力するSQL文

    SQLite バージョン3.7.10 を使用しています。 テーブルの構成などはこちらをご覧ください http://ideone.com/T50DH 次のような条件で結果を出力すると、 select sum(t5.amount * (t4.percent / 100.0)) result from ( ( select strftime('%Y', date) year, t2_key, t3_key, amount from t5 where strftime('%Y', date) = '2011' ) t5 inner join t2 on (t2.key = t5.t2_key and t2.name = 't2_name1') inner join ( select t4.* from t4 inner join t1 on (t4.t1_key = t1.key and t1.name = 't1_name1') ) t4 on (t5.t3_key = t4.t3_key and t5.year = t4.year) ); '2011'、't1_name1'、 't2_name1' の計算結果が出力されます。 例えばこの条件で、 '2011'ではなくて'2012'の計算結果を得たければ '2012'、't1_name1'、 't2_name1' の値をいちいち手動で入力してその都度求めれば出来るとは思いますが、 この3つの条件を全パターン出力してくれるようなSQL文を書くことはできないでしょうか? 例えば '2011'、't1_name1'、 't2_name1' の計算結果12300.0 '2011'、't1_name1'、 't2_name2' の計算結果・・・ '2011'、't1_name2'、 't2_name1' の計算結果・・・ '2011'、't1_name2'、 't2_name2' の計算結果・・・ '2012'、't1_name1'、 't2_name1' の計算結果・・・ '2012'、't1_name1'、 't2_name2' の計算結果・・・ '2012'、't1_name2'、 't2_name1' の計算結果・・・ '2012'、't1_name2'、 't2_name2' の計算結果・・・ というような結果を得たいです。 これはどのようなSQL文になるのでしょうか?

  • JOINを使ったSQL文を作成しようとしています。

    JOINを使ったSQL文を作成しようとしています。 以下の様な3つのテーブルがある場合のSQL文を教えて下さい ※勉強の為、適当なテーブルを作成しましたが、やりたい事は  JOINの中に更にJOINさせたSQL文を作成したいと思ってます 表A  USER_ID(プライマリキー)  NAME 表B  USER_ID(プライマリキー) ※表A.USER_IDと紐着く  BUMON(プライマリキー)  TERM(プライマリキー) 表C  BUMON(プライマリキー) ※表B.BUMONと紐着く  TERM(プライマリキー) ※表B.TERMと紐着く  MEMBER 【取得したい項目】  表A.USER_ID 【抽出条件】  表CのMEMBERの値が'10','20'以外(である表AのNAMEを取得)