すべてのカテゴリ » インターネット・パソコン » 技術・プログラミング

質問

終了

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文を入力すれば良いのでしょうか?

===補足===
追記

私のやりたいことは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を実行するのですが、中々出来ません。
どうかご教授お願い致します。

  • 質問者:sin
  • 質問日時:2014-09-24 16:31:10
  • 0

並び替え:

下記で出ないことはないと思います。がんばってください。
(見栄えのため全角スペースですがご容赦を。)

SELECT
  b.*
FROM bukken b
WHERE EXISTS (
  SELECT
    k.fid
  FROM fudou_kodawari2 k
  WHERE k.kid IN (1, 2, 3)
   AND k.fid = b.id
  GROUP BY k.fid
  HAVING COUNT(*) = 3
)

===補足===
HAVING句で指定する数値は、こだわり条件で選択された条件の個数を指定します。そのため、チェックボックスの個数には依存しません。

提示いただいたコード上では $ary の要素数ですね。count($ary)あたりで指定してください。

IN演算子で指定されたこだわり条件をすべて満たすfidは、IN演算子で指定された値の個数(レコード数)だけ存在します。そのため、
・1,2,3が指定されたら3行
・1,2,4,5が指定されたら4行
が抽出されるfidが対象となる物件です。

こだわり条件のテーブル設計じたいはケース・バイ・ケースなので、誤りとは言えません。正規化したという意味では正解だと思いますが、横に条件を持ったほうがパフォーマンスが上がる場合もあります。レコード数が増えてくれば尚更です。

ただ横持ちする場合は条件が増えた時にカラムを増やして対応する必要があるので、例のように条件(項目)が増える可能性が充分に考えられる場合は、今回の設計で良いと思います。

あとテーブルのカラム名は、誰が見てもわかる名前をつけるべきです。略名でつけてしまうと、自分が作ったものでも時間が経つと思い出すまで時間がかかるようになってしまいますよ。

この回答の満足度
  
参考になり、満足しました。回答ありがとうございました。
お礼コメント

お答えいただき誠にありがとうございます!

if(isset($_POST['kid'])and is_array($_POST['kid'])){
$ary = array_filter($_POST['kid'], function($v) {return is_numeric($v);});
$sqlK1 = 'EXISTS (SELECT k.fid FROM fudou_kodawari2 k WHERE k.kid IN ('.implode(',', $ary).') AND k.fid = b.id GROUP BY k.fid HAVING COUNT(*) = 3)';
}else{ //print '
こだわりがチェックされてません';
$sqlK1 = ' 1 ';
}

このようにチェックボックスの値ををうけるPHPを入力してみたのですが、HAVING COUNT(*) = 3)'; のところなんですが、=3じゃないと駄目なんでしょうか?チェックボックスが3個以外(1,2,4,5,6,7個)ついた場合はこの設計では難しいのでしょうか?

4のときはHAVING COUNT(*) = 4)';
5のときはHAVING COUNT(*) = 5)';
とその都度変更するのではシステム自体難しいかもしれません。(もちろん私が考えた条件でコードを書いてもらったので私の責任です)

もし難しいならばテーブルの構造だったり、システム自体見直したほうが良いのでしょうか?


恐縮ですが機会があればまたご教授いただけるとありがたいです!

関連する質問・相談

Sooda!からのお知らせ

一覧を見る