アプリ版:「スタンプのみでお礼する」機能のリリースについて

頭の整理ができないので技術的なこともさることながら、SQL構築の考え方もうかがいたいのですが、
以下のテーブルに対して、スペース区切りで複数キーワードをAND条件で結ぶとして

ID MyCol1 MyCol2
--------------------------
1 いちご みかんジュース
2 ぶどう いちごみるく
3 みかん すいかジュース
4 すいか めろんソーダ
5 めろん ぶどうガム

検索フォームに「いちご ソーダ(※スペース区切り)」と入れたら、IDの1、2、4がマッチするようにしたいです。

スペース区切りで複数キーワードをAND条件で結ぶSQLは、以前教わりました。

http://oshiete.goo.ne.jp/qa/1212708.html

$sql = 'select * from t_url';
if ($title != '') {
$titles = array();
foreach (preg_split('/(\s| )+/', $title) as $word) {
array_push($titles, "MyCol1 like '%$word%'");
}
$sql .= ' where (' . implode(' and ', $titles) . ')';
}

今回の質問は、受け取った$titleを「MyCol1」だけでなく「MyCol1かMyCol2」にも同じ照会する方法をうかがいたいです。


検索キーワードが「いちご ソーダ」だったとき、MyCol1だけなら、

and (MyCol1 like '%いちご%' and MyCol2 like '%ソーダ%')

でよいわけですが、MyCol2はどう熱かったらいいのでしょうか。

and (MyCol1 or MyCol2 like '%いちご%' and MyCol1 or MyCol2 like '%ソーダ%')

みたいにできればよいのでしょうが。
PHPのコードも、上記のものだとMyCol1にしか照会がかかりませんが・・・

A 回答 (2件)

and (concat(MyCol1,' ',MyCol2) like '%いちご%'


and concat(MyCol1,' ',MyCol2) like '%ソーダ%')
とでもすれば手っ取り早いと思いますが。

concat()・・・文字列をつなげます。

http://dev.mysql.com/doc/refman/5.1-olh/ja/strin …

具体的には、
ID Concat(MyCol1,' ',MyCol2)
--------------------------
1 いちご みかんジュース
2 ぶどう いちごみるく
3 みかん すいかジュース
4 すいか めろんソーダ
5 めろん ぶどうガム

となり、「いちご」と「ソーダ」をorでつなげば、1,2,4がでてきます。
(なお、andでつなぐと、質問にかかれた1,2,4でなく、1件もでてこないですが。)

なんで、,' ',をいれているかというと、

6 といち ごりら
とあると
Concat(MyCol1,MyCol2)
では、
6 といちごりら
となり、「いちご」が見つかってしまうためです。
    • good
    • 2
この回答へのお礼

Siegruneさん、非常にわかりやすくご回答いただき、大変参考になりました。

結果は完全に期待どおり、複数キーワードで複数カラムからの絞込みができるようになりました。

スペース区切りの複数キーワードについても、元質問を

array_push($titles, "concat(MyCol1,' ',MyCol2) like '%$word%'");

とすることでうまくいき、大変助かりました。

ありがとうございました。

お礼日時:2013/10/21 19:19

> 検索フォームに「いちご ソーダ(※スペース区切り)」と入れたら、IDの1、2、4がマッチするようにしたいです。



これだとMyCol1にもMyCol2にも「ソーダ」が含まれていない行や、MyCol1にもMyCol2にも「いちご」が含まれていない行もヒットするので、AND検索ではなくOR検索になりそうですが?

それから考えて、「MyCol1 と MyCol2 のどちらかに『いちご』または『ソーダ』が含まれるもの」という条件だと仮定すると、下記の様に単純に全条件をORでつなげれば対応できるかと。

SELECT * FROM tmp_table WHERE
MyCol1 LIKE '%いちご%' OR
MyCol2 LIKE '%いちご%' OR
MyCol1 LIKE '%ソーダ%' OR
MyCol2 LIKE '%ソーダ%';


また、2カラムに対するAND検索というと、「MyCol1 と MyCol2 のどちらかに『いちご』が含まれ、かつ、MyCol1 と MyCol2 のどちらかに『ソーダ』が含まれる」の様な条件が考えられますが、こちらは下記の様なSQLになります。

SELECT * FROM tmp_table
WHERE
(MyCol1 LIKE '%いちご%' OR MyCol2 LIKE '%いちご%') AND
(MyCol1 LIKE '%ソーダ%' OR MyCol2 LIKE '%ソーダ%')
;


蛇足ですが、外部に公開するようなシステムの場合は、入力値をそのままSQLに入れるのは危険ですのでプレースホルダを使うなどの対策をした方が良いです。
http://www.atmarkit.co.jp/fsecurity/column/ueno/ …
    • good
    • 0
この回答へのお礼

root139さん、詳しくご教示いただき大変ありがとうございました。

おかげさまで考え方、非常によく整理できました。
後学のため、ご提示のものも一通り試して結果拝見しました。

>入力値をそのままSQLに入れるのは危険

こちらについてもご忠告大変ありがとうございました。
まずはローカルで「やりたい形」を実現して、仰せのセキュリティ対策も施していきたいと思います。

お礼日時:2013/10/21 19:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す