質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

349閲覧

正規化した構成のデータの呼び出し(検索)について

chapp

総合スコア233

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/07/03 13:36

編集2018/07/06 09:15

お世話になります。PHPでMySQLを使ったウェブサービスを作っているのですが、以下のような正規化を行った構成のデータは、どのようなSQL文となるのかイメージ出来ずに質問いたします。

memberテーブル
no   name old  sex
1   田島  21  woman
2   佐藤  32  man
3   菊池  26  woman

kudamonoテーブル
no   name
1   いちご
2   みかん
3   バナナ
4   りんご
5   ぶどう

likeテーブル(メンバーが好きな果物を登録。memberテーブルのnoとmember_no、kudamonoテーブルのnoとkudamono_noは紐づいている)
no member_no kudamono_no
1    1     1
2    1     3
3    2     2
4    3     1
5    3     4
6    3     5

このテーブル構成にて、田島のデータは21歳の女性、好きな果物はイチゴとバナナです。

このような構成のテーブルで、年齢の範囲や性別、好きな果物をチェックボックスやセレクトボックスで選択し、該当するメンバーを呼び出したいと考えています。

ここで質問です。対象となる基本のテーブルがmemberテーブルかとは思うのですが、好きな果物はメンバー1人に対して複数あるので、負担なく検索するにはどのようなSQLとなるのかがイメージ出来ません。

以前、この果物は、memberテーブル内にカラムを設け、「ばなな,いちご,ぶどう」といった形で保存していたのですが、正規化した方が良いとのアドバイスをいただき今回のような構成にしたものの、今度は呼出す際の負担のないSQLに困っている次第です。

お忙しい中恐縮ですが、ご指南のほどよろしくお願いいたします。

■■ 追加情報 ■■
実際のテーブル構成は以下の通りです。
質問ではイメージしやすいようにと個人が好きな果物を例えにしていますが、実際は不動産物件情報で、それに付随する、「駅チカ物件」「ペット可」「デザイナーズ物件」などです。

ですので、

memberテーブル ⇒ property_dataテーブルであり(※)

kudamonoテーブル ⇒ osusumeテーブルであり

likeテーブル ⇒ property_data_osusumeであります。

※不動産物件という事ありカラムが多数あるので多くを省略しています。

これら構成の元、方位が西、または南西向きで、3LDK、ペット可で駅チカ物件と検索した際、該当する物件を抽出したいと考えたとき、例の果物に当たるosusumeが、チェックボックスでn個を検索条件とした場合、どのようなSQLになるのか?悩んでいるところです。

CREATE TABLE `property_data` ( `data_no` int(11) NOT NULL, `data_corporate_user_no` int(11) NOT NULL, `data_cate_b_no` int(11) NOT NULL, `data_cate_m_no` int(11) NOT NULL, `data_pr` varchar(255) NOT NULL, `data_bukkenn_name` varchar(255) NOT NULL, `data_train1` varchar(64) NOT NULL, `data_train_station1` varchar(64) NOT NULL, `data_train_station_toho1` int(11) NOT NULL, `data_addr1` varchar(128) NOT NULL, `data_addr2` varchar(128) NOT NULL, `data_addr3` varchar(255) NOT NULL, `data_houi` enum('','北','北東','東','南東','南','南西','西','北西') NOT NULL, `data_madori1` varchar(16) NOT NULL, `data_madori2` enum('ワンルーム','K','DK','LK','LDK','SK','SDK','SLK','SLDK') NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- テーブルのデータのダンプ `property_data` -- INSERT INTO `property_data` (`data_no`, `data_corporate_user_no`, `data_cate_b_no`, `data_cate_m_no`, `data_pr`, `data_bukkenn_name`, `data_train1`, `data_train_station1`, `data_train_station_toho1`, `data_addr1`, `data_addr2`, `data_addr3`, `data_houi`, `data_madori1`, `data_madori2`) VALUES (20, 12, 1, 1, '駅近、ファミリータイプ物件!通り沿いで交通に便利なの物件です。', 'サニーレジデンス301', 'JR上越線', '長岡', 15, '新潟県', '長岡市', '旭町2丁目3-31', '東', '3', 'DK'), (21, 12, 1, 1, '駅近、ファミリータイプ物件!通り沿いで交通に便利なの物件です。', 'サニーレジデンス402', 'JR上越線', '長岡', 15, '新潟県', '長岡市', '旭町2丁目3-25', '南西', '3', 'DK'), (22, 13, 2, 10, 'ファミリー向けです!', 'エヌステージ似弐号館', 'JR弥彦線', '北三条', 2, '新潟県', '三条市', '本町1-3', '東', '4', 'LDK'), (23, 13, 2, 10, 'ファミリー向けの物件です!', 'エヌステージ壱号館', 'JR弥彦線', '北三条', 10, '新潟県', '三条市', '本町1-3-17', '南東', '4', 'LDK'), (24, 14, 1, 4, 'アスファルト、街灯、屋根付きのセキュリティーの高い駐車場', 'アテンド駐車場', 'JR上越線', '長岡', 20, '新潟県', '長岡市', '土合5丁目10-17', '北', '3', 'DK'), (25, 12, 1, 1, 'エントランスが貴方の行き帰りをおもてなしします', 'Nステージ', 'JR信越本線(直江津~新潟)', '亀田', 40, '新潟県', '新潟市江南区', '二本木4丁目5-37', '南', '2', 'K'), (26, 12, 2, 12, '広々した憧れの一軒家 二世帯でも対応可能な広さです', '三和区錦 一軒家', '北越急行ほくほく線', '大池いこいの森', 50, '新潟県', '上越市', '三和区錦1180-4', '南東', '5', 'LDK'), (27, 14, 1, 1, '加治川のせせらぎ日頃の疲れを癒してくれます', 'ライフル', 'JR羽越本線', '新発田', 5, '新潟県', '新発田市', '豊町2丁目9-1', '北東', '3', 'DK'), (29, 12, 2, 12, '広々した憧れの一軒家 二世帯でも対応可能な広さです', '三和区錦 一軒家', '北越急行ほくほく線', '大池いこいの森', 25, '新潟県', '上越市', '三和区錦1180-1', '南', '5', 'LDK'), (30, 13, 2, 17, '想定利回り10%強! 現況満室の高収益物件!', 'エヌステージ似弐号館', 'JR上越線', '越後堀之内', 2, '新潟県', '三条市', '本町1-3', '南', '4', 'LDK');
CREATE TABLE `osusume` ( `osusume_no` int(11) NOT NULL, `osusume_name` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- テーブルのデータのダンプ `osusume` -- INSERT INTO `osusume` (`osusume_no`, `osusume_name`) VALUES (19, 'お風呂広い'), (7, 'シニア(60歳以上)入居可'), (22, 'デザイナーズ物件'), (13, 'ファミリー向け'), (17, 'フリーレント'), (9, 'ペット可'), (12, 'ルームシェア可'), (21, 'ロープライス・フローライフ'), (11, '事務所利用可'), (6, '二人入居可'), (14, '保証人不要'), (1, '女性限定'), (8, '子供可'), (4, '学生可'), (18, '更新料不要'), (10, '楽器可'), (3, '法人可'), (2, '男性限定'), (20, '訳アリ物件'), (23, '駅チカ物件');
CREATE TABLE `property_data_osusume` ( `property_data_no_osusume` int(11) NOT NULL, `property_data_data_no_osusume` int(11) NOT NULL, `property_data_osusume_no` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- テーブルのデータのダンプ `property_data_osusume` -- INSERT INTO `property_data_osusume` (`property_data_no_osusume`, `property_data_data_no_osusume`, `property_data_osusume_no`) VALUES (1, 1, 1), (2, 1, 7), (3, 1, 12), (4, 2, 22), (5, 2, 3), (6, 2, 8), (7, 3, 12), (8, 3, 18), (9, 4, 22);

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/07/03 13:52

CREATE文とサンプルデータのINSERT文を提示してください。
m.ts10806

2018/07/04 00:36

MySQLのみの回答で問題ないのでしょうか。
m.ts10806

2018/07/04 00:37

また、「アドバイスをいただき~~~」の結果、実際に自身で組んでみたコード(SQLだけでも)も提示してください。
guest

回答3

0

ベストアンサー

こういう場合は、テーブル結合(join)というのを使います。
「いちごかバナナが好きな女性」を探すなら

SQL

1SELECT 2 m.* 3FROM 4 member AS m 5INNER JOIN 6 member_kudamono AS mk 7 ON 8 m.no = mk.member_no 9INNER JOIN 10 kudamono AS k 11 ON 12 mk.kudamono_no = k.no 13WHERE 14 k.name IN ('いちご', 'バナナ') 15 AND m.sex = 'woman'

です。
※質問文では「like」テーブルとなっていたところを「member_kudamono」テーブルに改名しています(SQLにおいて、おそらくlikeは予約語なので、使い勝手&可読性が悪くなるため)。
テーブル構造は「like」テーブルと同様です。

ただ、チェックボックス等で選ばせるのであれば、kudamonoのnameを表示、noをチェックボックスのvalueにしておけば、kudamonoのjoinは必要なくなります。

SQL

1SELECT 2 m.* 3FROM 4 member AS m 5INNER JOIN 6 member_kudamono AS mk 7 ON 8 m.no = mk.member_no 9WHERE 10 mk.id IN (1, 3) 11 AND m.sex = 'woman'

質問へのコメントを受けて……。

すみません、回答が遅くなりました。
上記2つめのSQLがエラーになった件については、こちらで提示したSQLが誤っていたので訂正させていただきました( k.name IN ('いちご', 'バナナ')mk.id IN (1, 3) )。大変失礼いたしました。

もう一つのSQLでデータが取れなかった原因は調査しておりませんが、今回、実際のテーブルを提示していただいたので、そちらを元に改めて説明させていただきます。

条件が「OR」でなく「AND」とのことですので、この場合は(データ量が多い場合、若干速度面で問題はありそうですが)EXISTSを使うと可読性の良いSQLができます。

sql

1-- 事前準備SQL(テストデータに「ペット可、かつ、駅チカ物件」が存在しなかったので、テストデータを追加) 2INSERT INTO property_data_osusume ( 3property_data_no_osusume, 4property_data_data_no_osusume, 5property_data_osusume_no 6) 7VALUES 8('10', '20', '9'), 9('11', '20', '23'), 10('12', '21', '9'), 11('13', '21', '23') 12;

sql

1-- 検索SQL 2-- 条件:方位が西、または南西向きで、3DK、ペット可で駅チカ物件 3-- ※元の条件では「3LDK」と書かれていましたが、テストデータに「3LDK」のデータが無かったので、3DKに変更しています。 4SELECT 5 p.* 6FROM 7 property_data AS p 8WHERE 9 p.data_houi IN ('西', '南西') 10 AND 11 (p.data_madori1 = '3' AND p.data_madori2 = 'DK') 12 AND 13 EXISTS( 14 SELECT 15 * 16 FROM 17 property_data_osusume AS po 18 INNER JOIN 19 osusume AS o 20 ON 21 po.property_data_osusume_no = o.osusume_no 22 WHERE 23 p.data_no = po.property_data_data_no_osusume 24 AND 25 o.osusume_name = 'ペット可' 26 ) 27 AND 28 EXISTS( 29 SELECT 30 * 31 FROM 32 property_data_osusume AS po 33 INNER JOIN 34 osusume AS o 35 ON 36 po.property_data_osusume_no = o.osusume_no 37 WHERE 38 p.data_no = po.property_data_data_no_osusume 39 AND 40 o.osusume_name = '駅チカ物件' 41 )

 


なお、多少可読性を犠牲にしてもいいから、とにかく速いSQLを!ということであれば、下記のような方法もあります。

sql

1-- 検索SQL 2-- 条件:方位が西、または南西向きで、3DK、ペット可で駅チカ物件 3-- ※元の条件では「3LDK」と書かれていましたが、テストデータに「3LDK」のデータが無かったので、3DKに変更しています。 4SELECT 5 p.* 6FROM 7 property_data AS p 8INNER JOIN 9 property_data_osusume AS po 10 ON 11 p.data_no = po.property_data_data_no_osusume 12INNER JOIN 13 osusume AS o 14 ON 15 po.property_data_osusume_no = o.osusume_no 16WHERE 17 p.data_houi IN ('西', '南西') 18 AND 19 (p.data_madori1 = '3' AND p.data_madori2 = 'DK') 20 AND 21 o.osusume_name IN ('ペット可', '駅チカ物件') 22GROUP BY 23 p.data_no 24HAVING 25 COUNT(*) = 2 -- o.osusume_nameのINの中に設定した値の数

解説:
INで「ペット可、または、駅チカ物件」としているので、いったんJOIN結果として

data_no osusume_name


21 ペット可
21 駅チカ物件

が取得できる
⇒data_noでGROUP BYする
⇒data_no=21のcountは2となる
⇒HAVING COUNT(*) = 2としているので、条件に合致するレコードとなり、取得できる

こちら、「ペット可」しか条件に合致しない物件の場合(仮にdata_no=99とする)、

data_no osusume_name


99 ペット可
が取得できる
⇒data_noでGROUP BYする
⇒data_no=99のcountは1となる
⇒HAVING COUNT(*) = 2としているので、条件に合致しないレコードとなり、取得できない

投稿2018/07/03 16:17

編集2018/07/09 04:06
nak

総合スコア696

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chapp

2018/07/06 07:07

nakさま ご親切なアドバイスをありがとうございます。 また、SQLのご提示、重ねて御礼申し上げます。 ご提示して下さったSQLをphpMyAdminにて実行しているのですが、結果が返ってきません(0件表示) また、2つ目のSQLを実行すると、以下の表記のもとエラーとなってしまいます。 #1054 - 列 'k.name' は 'where clause' にはありません。 left joinはよく使うので、親しみやすい?内容ですが、 k.name IN ('いちご', 'バナナ')や、 k.name IN (1, 3)の箇所など、普段触ることない内容なので、お教えいただいたソースのどこが原因で動かないのか?お教えいただければありがたいです。
nak

2018/07/09 04:19

大変遅くなりましたが、回答を修正いたしましたのでご確認をお願いいたします。 なお、気になった点として……。 例として新たに提示していただいたテーブルですが、プライマリキーもインデックスも貼られていないようです。 「テストデータだから省いた」ということであれば良いのですが、そうでないなら、最低限プライマリキーは貼ったほうが良いと思います(インデックスはお好みで)。 プライマリキー(=主キー)とインデックスについての説明 ※Accessに関する説明ページですが、概念自体はMySQLでも一緒です。 https://www.nishi2002.com/4002.html MySQLで主キー(=プライマリキー)やインデックス等を追加する方法 http://tech.pjin.jp/blog/2017/05/31/mysql-key-sql1/
chapp

2018/07/14 07:03 編集

nakさま お世話になっております。まずはもって、お礼のお返事が出来なかったことお詫びいたします。 送信したつもりでしたが、きちんと送信が出来ていなかったようで、この状況に昨夜気づいた次第です。ご親切にご対応いただいているにも関わらず、申し訳ございませんでした。 さて、未だ上手く行っていない状況なのですが、新たにご教示いただいた、EXISTS()を使って幾度も試しているのですが、ファミリー向け、フリーレント、ペット可、駅チカ物件など、検索条件として複数あるうち1つの場合はきちんと結果が返ってくるのですが、複数選択した場合データを抽出することが出来ません。 以下は、実際に呼び出している際のSQL(WHERE以下の部分)です。 また、以下のソースにGroup byを設けていますが、これをしないと、同じデータが羅列してしまうためこのような記述を行っています。 そもそも問題ありな記述なのか?と不安もアリ書き残しました。 これまで、多くの説明を頂いているため恐縮ですが、引き続き、ご指導いただければ幸いです。 よろしくお願いいたします。 1つの場合 WHERE property_data.data_cate_m_no = '1' AND property_data.data_chintai_price >= 0 AND property_data.data_addr2 IN ('新潟市北区','長岡市') AND property_data.data_update_plan_date >= '2018-07-14' AND property_data.data_state = '' AND corporate_user.corporate_state = '' AND EXISTS( SELECT * FROM property_data_osusume AS PDO INNER JOIN osusume AS O ON PDO.property_data_osusume_no = O.osusume_no WHERE property_data.data_no = PDO.property_data_data_no_osusume AND osusume_no = '3') GROUP BY data_no ORDER BY property_data.data_update_plan_date DESC LIMIT 0, 20; 複数(2つ)の場合 WHERE property_data.data_cate_m_no = '1' AND property_data.data_chintai_price >= 0 AND property_data.data_addr2 IN ('新潟市北区','長岡市') AND property_data.data_update_plan_date >= '2018-07-14' AND property_data.data_state = '' AND corporate_user.corporate_state = '' AND EXISTS( SELECT * FROM property_data_osusume AS PDO INNER JOIN osusume AS O ON PDO.property_data_osusume_no = O.osusume_no WHERE property_data.data_no = PDO.property_data_data_no_osusume AND osusume_no = '3') AND EXISTS( SELECT * FROM property_data_osusume AS PDO INNER JOIN osusume AS O ON PDO.property_data_osusume_no = O.osusume_no WHERE property_data.data_no = PDO.property_data_data_no_osusume AND osusume_no = '2') GROUP BY data_no ORDER BY property_data.data_update_plan_date DESC LIMIT 0, 20;
nak

2018/07/14 07:29

ご丁寧にコメントありがとうございます。恐縮です。 さて、 > ファミリー向け、フリーレント、ペット可、駅チカ物件など、検索条件として複数あるうち1つの場合はきちんと結果が返ってくるのですが、複数選択した場合データを抽出することが出来ません。 とのことですが、何点か確認させてください。 確認1-1.「ペット可」と「駅チカ物件」の2つが選択されている場合、「ペット可、かつ、駅チカ物件」をご所望ですか?それとも、「ペット可、または、駅チカ物件」をご所望ですか? (1-1への回答が「ペット可、かつ、駅チカ物件」だった場合のみ) 確認1-2. 先日、こちらで提示させていただいた「方位が西、または南西向きで、3DK、ペット可で駅チカ物件」のSQLは、想定どおりの動作になりましたか? ※本物のデータではなく、chappさんが質問欄に貼ってくださったテストデータ&私が回答欄で追加したテストデータに対して、「方位が西、または南西向きで、3DK、ペット可で駅チカ物件」を探すSQLを実行してみてください。 確認2. 動作しないSQLのWHERE句部分を頂戴いたしましたが、実際に動くSQLで動作確認をさせていただきたいため、WHERE句以外も含めた「SQL全文(=そのまま動かせるSQL)」をいただけますと幸いです。 --- > また、以下のソースにGroup byを設けていますが、これをしないと、同じデータが羅列してしまうためこのような記述を行っています。 回答修正後に書かせていただいたSQLの場合、テーブルJOINをしていないので、同じデータは羅列しない想定でした。 この点につきましては、いったん「確認2」にてSQL全文を拝見させていただいてからの回答とさせてください。
chapp

2018/07/14 10:39 編集

nakさま お世話になっております。恐縮しながらも、実際に作っている構成をそのままアップしようと、テストをしながら準備していたところ、EXISTS()を生成するスクリプトに不備があること確認いたしました。 誤った値が書き込まれ、結果的に正常な動きになっていなかったのが原因でした。 nakさまのお返事が無かったら、誤りに気付かなかったと思います。ありがとうございます! それと、GROUP BYの件ですが、先のお返事にある「テーブルJOINをしていないので」からして、「テーブルをJOINしている場合は必要である」と認識で宜しかったでしょうか? この度の質問は簡素化するために無駄と思われるテーブルは省いてご説明したのですが、実際は複数のテーブルをJOINしています。 実際のテーブル構成をあげることに問題はありませんが、そこそこの数になるので申し訳なくて・・・ 最後にGROUP BYの疑問以外は解決いたしました。最後にもう1点、ご教示いただければ幸いです。 よろしくお願いいたします。
nak

2018/07/15 03:10

お疲れ様でした! > それと、GROUP BYの件ですが、先のお返事にある「テーブルJOINをしていないので」からして、「テーブルをJOINしている場合は必要である」と認識で宜しかったでしょうか? はい、JOIN対象のテーブルのデータが1対Nになる場合は必要かと思います(1対1の場合はGROUP BYしなくても問題はありません)。 なお、別解として「GROUP BYではなく、DISTINCTを使う」という方法もありますが……どちらの方法でも期待された結果になると思いますので、お好きなほうをご利用ください。 追伸: 以下、今回のQAの「改善提案」です。 今後の質問の際の参考になれば幸いです(クレームではありませんので、その点ご理解ください)。 ・質問時、仕様は(決まっているのであれば)細かいところも含めて明確にする。 →回答の変遷を見ていただいたのでおわかりかと思いますが、「女性、かつ、イチゴ"と(=AND)"バナナが好き」と「女性、かつ、イチゴ"か(=OR)"バナナが好き」では、発行するSQLが全く異なります。  SQLだけでなく、プログラムの場合も「一見似たような条件だが、プログラムに落とすと全く違うコートになる」こともありますので、質問の時点で仕様が明確なのであれば、明記していただいたほうが、最初から「期待どおりの回答」がつきやすくなると思います。 ・質問文中で提示している内容を元に話をできるようにする。 →「実データでやってみたらうまくいかない」「実はSQLを組み立てる処理の部分に問題が……」というのは、回答者側の環境では再現不能です(情報がないため)。  質問者と回答者が同じ土俵で話をできるようにしていただけると良いかと思います。    今回の場合、提示していただいているのは「テストデータと仕様」、質問内容は「どのようなSQL文となるのか」なので、まずは「テストデータに対して、回答されたSQLを使い、期待した結果が取得できるかどうか(条件文等を、回答されたSQLを元に自分で変えてみたりするのは可)」を(PHPのプログラム経由ではなく)SQL単体で確認していただいて問題がなければ、「この質問」としてはゴールに到達したことになるのかな、と思いました。    その後、実データに対して、回答を元に(プログラム経由ではなく手作業で)作成したSQLをテストしてみる→うまくいったらPHPのプログラムに組み込んでテストする、という手順で作業していけば、ご自身で調査をされる時も、どの部分に不具合があるのか判断しやすいかと。  もし、「テストデータではうまくいったが、実データへのSQL発行時だけ、どうしても期待した結果にならない」のであれば、実データ(全テーブルの各数レコードずつを抜粋したもの)を元にした質問を改めて立てれば良いですし、「実データへのSQLも成功したが、PHPに組み込んだ時だけうまくいかない」のであれば、PHPのプログラムを含めた質問を立てれば良いと思います。
chapp

2018/07/15 12:53

nakさま お世話になっております。お休みのところ、ご丁寧なアドバイスをありがとございます。 Group Byの件、ありがとうございます。認識通りで安心いたしました。 また、質問の内容の件、仰る通りですね。この度の一連のやり取りの中で、至らぬ点を気付かされました。ご親切からくるご指摘と受け止めております。 以上、改めて、この度の回答、ありがとうございました。 ソースだけでなく、それぞれに説明を頂けたことで理解も深まり、とても感謝しています。 長々とお付き合いいただき、ありがとうございました!
guest

0

エスパー回答です
勝手に、「動的に where 条件を追加したい」という質問と読み替えました。

その場合、if で条件分岐し、sql 文とバインドする変数を追加する事で実現できます。

エスパーな上に、回答はコピペですが参考まで。
条件検索におけるプリペアドステートメントの使用
escape_wildcard()の実装は、本を買って確認してくださいw

answerer ockeghem [12月18日 17:19]

検索条件が動的に変わる場合、プレースホルダ(プリペアードステートメント)をどう使って良いかはよくある質問だと思います。「体系的に学ぶ 安全なWebアプリケーションの作り方」という本のP135にサンプルが出ています。以下に該当する部分を引用します。

php

1 // 基本となるSQL 2 $sql = 'SELECT id, title, author, publisher, date, price FROM books'; 3 if ($title !== '') { // 検索条件titleの追加(LIKE) 4 $conditions[] = "title LIKE ? ESCAPE '#'"; 5 $ph_type[] = 'text'; 6 $ph_value[] = escape_wildcard($title); 7 } 8 if ($price !== '') { // 検索条件priceの追加(大小比較) 9 $conditions[] = "price <= ?"; 10 $ph_type[] = 'integer'; 11 $ph_value[] = $price; 12 } 13 if (count($conditions) > 0) { // WHERE句がある場合 14 $sql .= ' WHERE ' . implode(' AND ', $conditions); 15 } 16 $stmt = $mdb2->prepare($sql, $ph_type); // SQL文の準備 17 $rs = $stmt->execute($ph_value); // バインド・問い合わせ実行

ご覧のように、WHERE句の断片を配列に追加していき、同時に型と値も別の配列に追加しているだけです。

面倒なように見えるかもしれませんが、単純な繰り返しなので、難しくはないと思います。

投稿2018/07/09 05:20

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chapp

2018/07/10 06:37

te2jiさま ご親切なアドバイスをありがとうございます。 お返事までお時間を頂きましたが、動的な検索条件等、応用的なアドバイス、とても参考になりました。ありがとうございました!
guest

0

こうしてみてください

SQL

1create table member(uid int primary key,uname varchar(20),old int ,sex int); 2insert into member values 3(1,'田島',21,2), 4(2,'佐藤',32,1), 5(3,'菊池',26,2); 6 7create table kudamono(kid int primary key,kname varchar(20)); 8insert into kudamono values 9(1,'いちご'), 10(2,'みかん'), 11(3,'バナナ'), 12(4,'りんご'), 13(5,'ぶどう'); 14 15create table member_kudamono(xid int primary key,uid int,kid int); 16insert into member_kudamono values 17(1,1,1), 18(2,1,3), 19(3,2,2), 20(4,3,1), 21(5,3,4), 22(6,3,5);
  • 検索

SQL

1select t1.uid,t1.uname,t4.kgroup from member as t1 2inner join ( 3select t2.uid,group_concat(kname) kgroup 4 from member_kudamono as t2 5inner join kudamono as t3 on t2.kid=t3.kid 6group by uid 7) as t4 on t1.uid=t4.uid

投稿2018/07/04 00:35

yambejp

総合スコア114581

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chapp

2018/07/06 10:51

yambejpさま ご親切なアドバイスをありがとうございます。 また、カラム名を変えてのcreatet文をありがとうございます。 ご提示いただいたselect文を実行しているのですが、年齢や性別の他、チェックベックスなどで果物をN個を絞込検索するにはどのようなWHERE文になるのでしょうか?試しているのですが、いずれもエラーとなってしまって・・・ 引き続き、ご指導頂戴できたら幸いです。 よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問