• ベストアンサー

スペースによる絞り込み検索をSQL文だけで実現したい

単語がスペースで区切られている場合、 文字列を分割して配列に入れ foreachなどでANDを足していく方法が主流(?)なようなのですが、 これをSQL文だけで実現することは可能でしょうか? いろいろ調べたのですが、 SQL文にforなどの繰り返しがなさそうなのでむずかしいのかなと思っているのですが・・・ MATCHやAGAINSTを使って実現できますか? あるいはストアドプロシジャなどでも構わないのですが・・ 知識が乏しいので用語の使い方などもおかしなところがあるかと思いますが、よろしくお願いします。

  • MySQL
  • 回答数4
  • ありがとう数2

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

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

もしかりに「鈴木 一郎」を分解して「%鈴木%」と「%一郎%」のANDを とったとしても、「鈴木一郎」のみをヒットさせることはできません。 たとえば「鈴木田 真一郎」さんとかいたらヒットします。 またLIKEでパフォーマンスが期待できるのは前方一致または後方一致の どちらかの場合のみです。 まぁ数万件レベルであれば%%のような構文でもそんなにスピードは 気にしなくても大丈夫でしょうけど、スピード重視なら全文検索でしょうね。 (2バイト文字の全文検索はMySQLのバージョンに依存します) 限られた用途だけでしたら#3さんのようなやり方で where name like CONCAT('%',replace('鈴木 一郎',' ',''),'%'); などとする手はあるでしょう きちんとやりたいなら、やはりSQLではなくプログラムレベルで 検索文字を分解して、SQLに渡してやる配慮が必要ではないでしょうか? 実際、キーワード渡しをするのであればそれなりのインタフェースが 必要でしょうし、インジェクション処理なども必要になるでしょうから 単純にはいきませんよ

その他の回答 (3)

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.3

最初から全角スペースで区切られていると分かっているのなら。 where name like '%' || replace('鈴木 一郎',' ','') || '%'; で検索できると思いますが。

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

>単語がスペースで区切られている場合、 具体的になにをしたいのかがわかりませんが そう言う場合は全文検索が効率的では?

madman666
質問者

補足

わかりにくくてすみません; たとえば、 id,name 1,鈴木一郎 2,山田二郎 3,佐藤三郎 4,田中四郎 というテーブル「member」があります。 現時点では、 検索フォームに「鈴木」と入れて検索できるまで作れたのですが、 「鈴木 一郎」のように、スペース区切りでの検索ができないのです。 $_GET['keyword']をcolnameに入れて、 WHERE name LIKE %colname% のようにしています。 この「鈴木 一郎」という入力値をスペースで分割して、 ANDでつないで、キーワードとして絞り込みたいのです。 つまりはyahooやgoogleのような検索ということでしょうか。 このようなものは全文検索で実現できるのでしょうか? ほんとうに説明が下手でもうしわけありませんが、 よろしくお願いします。

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

回答ではありません。 何度読んでも、どういうデータがあってそこからどんな結果を抽出しようと しているのかイメージがつかめません。もう少し、具体的にイメージできる ような補足がないと回答がつかない気がします。 #私もMysqlのストアドプロシージャは分からないので、補足されても、答え #る自信はありませんが。

関連するQ&A

  • スペース区切りによるAND検索をSQL文だけで実現したい

    スペース区切りによるAND検索をSQL文だけで実現したい いわゆるWeb検索等で利用するスペース区切りでのAND検索を SQL Serverでも実現可能かどうかを調べています。 結合に使用するため、プログラムからSQLを組み立てる事が出来ません。 なお、検索したい対象は一時テーブル内の小数データなので、パフォーマンスは特に問題は有りません。 ただし、一時テーブルなのでCONTAINS等を使用する事が出来ません。 せめて一時テーブルに対するフルテキスト検索が出来れば問題ないのですが、、、 以上、よろしくお願いします。

  • エクセルでSQLでいうところの「RPAD」を実現したい

    エクセルでSQLでいうところの「RPAD」を実現したいのですが 可能でしょうか? 「RPAD」とは RPAD(文字列、10) とすると文字列が10桁未満でもスペースを補充して 10桁にして返すものです。 何かご存知の方レスお願いします。

  • SQLの DELETE文を関数で実現するアイデア?

     当方、エクセルは一度も操作したことがありません。それなのに 1、クロス集計クエリーをエクセルで実現する。 2、ユニオンクエリ―をエクセルで実現する。 3、SQL言語で全ての操作を実現する。  以上をVBAコードやマクロを使わないで式(関数)一発で可能とするに挑戦中。 1、クエリーの結果をシートに表示する。 2、Delete文の実行を可能にする。 【質問】SQLの DELETE文を関数で実現するアイデアとは? 今、私が、考えているアイデアは、 Step1:削除対象の先頭列に"#delete"を書き込むUpdate文を実行する。 Step2:先頭列に"#delete"のある行を、エクセルの.Delete で削除する。 Step2の対案: 先頭列に"#delete"のある行を不要行と見做して必要行を繰り上げて詰める。  エクセルユーザーが、《テーブルシート》《データ入力シート》《レポートシート》という考えでシート設計していれば、現行の有力候補でOKだと思います。が、「あくまでもテーブルの行だけを削除しなきゃーダメ1」と言われれば、対案を考えざるを得ません。  で、皆さん、グッドアイデアはありませんか?

  • SQL文の書き方について

    SQLServer2005で、次のような品物の単価の履歴を表すテーブルを作りました。「,」は列の区切りです。 ID,Sort,Name,Price,Effective,Time 1,1,りんご,100,True,2009/4/1 2,3,なし,120,True,2009/4/1 3,2,ぶどう,150,True,2009/4/1 4,4,ばなな,80,True,2009/4/1 5,1,りんご,110,True,2009/4/20 6,3,なし,100,True,2009/4/20 7,3,なし,90,True,2009/4/25 8,4,ばなな,False,2009/4/25 このテーブルから、Effectiveが、Trueで、最新の単価をSort順に抽出するSQL文が判りません。 SELECT * FORM テーブル名 WHERE (Effective=1) ORDER BY Sort に、何を加えれば実現可能でしょうか? どなたか?詳しい方がいらっしゃいましたら、教えてください。 SQL文の初心者なので、簡単なことなんでしょうが、よろしくお願いいたします。入門書を読めば読むほど、こんがらかって、困っております。なお、Sortの部分は、正規表現的に問題があるので、見直そうと考えています。

  • POSTした文字列をSQLコマンドに整形したい

    検索フォームに入力した単語に該当するtitleをSQLで検索するようなPHPを作成したい場合、 たとえば検索フォームに「php 連想配列 作成」と入力したらまず $key=_POST["key"]; として$keyに文字列を格納し、この後全角、半角問わず、スペースで3つの文字列を区切り、その文字列から配列を作成し、最終的に $keys=sprintf("php"or "連想配列" or"作成"); $sql = sprintf("SELECT * FROM dbname WHERE (title like".$keys.") ORDER BY id"); $result=mysql_query($sql, $link); while($row=mysql_fetch_assoc($result)) { print($row[title]) } というようなコードで出力すると思います。 この、上の$keyから$keysまでのコードが書けません。 がんばったのですが、正規表現を組みあわせたりすると途端にごちゃごちゃになります。 $keyから$keysまでのコードをどなたか教えていただけないでしょうか。 $keyから全角、半角問わず、スペースで3つの文字列を区切り、その文字列から配列を作成し、$keysに該当する変数を作成するコードです。 もしかしたら配列にしなくてもいい方法があるのかもしれませんが、私には思いつきませんでした。 どなたか、ご教示のほど、どうかよろしくお願いします。

    • ベストアンサー
    • PHP
  • プレインPHPでのSQL検索結果取得

    初心者の質問ですみません。 フレームワークをずうっと使って来たのですが、フレームワークを使わずに検索をしようとしたところ、全く思うようにいかず困っています。 SELECT * FROM table のような単純なSQL文なのですが、PEARを使って $sql = "SELECT * FROM table"; $result = $conn->query($sql); としvar_dumpしてみると、期待していたSQLのデータが表示されません。 フレームワークを使っていると、この時点でどのフレームワークでもきれいに連想配列で表示できていました。 その辺が、フレームワークのフレームワークたるゆえんなのでしょうか..... ただ、結果は取得できているようで、 $count = $result->numRows(); としてやると正しい件数が表示されますし、カラム名を指定して while($rs = $result->fetchRow(DB_FETCHMODE_ASSOC)){ echo $rs['column_name']; } としてやるとカラムの値を表示します。 やりたいこととしては、検索結果を連想配列で取得し、foreachで行ごとに処理を行うことで、whileで$rs['column_name']を取得できることから、最悪でも力技で行ごとにカラム情報を全て取得して配列を作ってやることはできるとは思うのですが、もっと良い方法が無いはずがないと思います。 教えていただけますでしょうか。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • 入力データの半角スペースと全角スペースを区別させる方法

    データベースに文字列を保存する際、既に同じ文字列が保存されていないか事前にチェックをかけているのですが、この時半角スペースが入った文字列と、全角スペースが入った文字列を同じものと認識してしまい、これを区別したいのですが、どういった方法があるのでしょうか。 具体例を出しますと、 「AAA BBB」(間の空白は全角スペース)を入力する際、同じ文字列が同じフィールドに保存されていないか、SQLのWHERE句で「フィールド名="AAA BBB"」を指定して検索し、同じ文字列があれば警告を出しているのですが、「AAA BBB」(間の空白は半角スペース)にも検索でマッチしてしまいます。 この検索の時に「AAA BBB」をマッチさせないようにしたいのです。 OS:Linux MySQLバージョン:5.1.22 文字コード:UTF-8 です。 よろしくお願いします。

  • エクセル関数の検索・抽出・置換えについて質問です。

    以前 質問して、 素晴らしいマクロを教えて頂きました。 仕事が早くでき、楽しくなってきたところ、 なんと会社で不具合があり、マクロ禁止になってしまいました・・・  Σ( ̄□ ̄) 改めて質問します! 2列の『旧 語録』の文に、 5列の『単語表・旧』が含まれていれば、 その単語だけが、 5列の右隣の、6列の『単語表・改正後』に変わり、 3列の『改正後の語録』のような文になるようにしたいのです。 5&6列の『単語表』の配列は変えずに、 関数で どうにかなるでしょうか? 回答を、心から お待ちしております。

  • forを使わずにforeach文のみでループを回す

    ○質問の主旨 先日、下記の質問をしました。 PHPのfor文とforeach文の使い方 http://okwave.jp/qa/q8812443.html この例では,for文とforeach文を使って、 ・果物の名前を4回繰り返す ・繰り返しの2回目と4回目は、"食べてください"という文字列を入れる というプログラムを実現しています。 今回は同じ出力をするにあたって、 繰り返しはforeachのみで実現したいと考えています。 どのように修正すればよろしいでしょうか? ご存知の方がいらっしゃいましたら、 ご教示を願います。 ○質問の補足 このようなプログラムにしたいと考えています。 $fruits = array("りんご", "ばなな", "ぶどう", "みかん"); foreach ($fruits as $value) { // 果物の名前を4回繰り返して2回目と3回目は"食べてください"を入れる if (($i == 1) || ($i == 3)) { echo "食べてください"; echo "<br/>"; }; echo $value; echo "<br/>"; } 完成イメージはこんな感じです。 (1回目のループ) りんご ばなな ぶどう みかん (2回目のループ) 食べてください りんご ばなな ぶどう みかん (3回目のループ) りんご ばなな ぶどう みかん (4回目のループ) 食べてください りんご ばなな ぶどう みかん ○前回のプログラム for($i = 0; $i < 4; $i++) { if (($i == 1) || ($i == 3)) { echo "食べてください"; echo "<br/>"; }; $fruits = array("りんご", "ばなな", "ぶどう", "みかん"); foreach ($fruits as $value) { echo $value; echo "<br/>"; } }

    • ベストアンサー
    • PHP
  • MySQLで全文検索について

    MySQLで全文検索を行いたく、色々と調べ、試行錯誤をしたのですが どうしてもできないので、mysqlでの全文検索のやり方がわかるかたがいらっしゃいましたら お教え願えますでしょうか。 私がやったこと 0。Mysqlのバージョン 5.5.23をインスコ  my.confにft_min_word_len=1を追加 mysql再起動 1。MyISAM型のbookテーブルを作成(utf8_general_ciでとりあえず idとsearch_wordsという2カラムのみ idをprimaryに設定) 2。検索対象であるsearch_wordsをFulltext型に変換   sql> alter table book add fulltext( search_words ); 3。データを登録   insert into book (id, search_word) value (1, '夏目漱石 こころ natsume souseki kokoro BOOK-NO-012 時は明治末期。夏休みに鎌倉へ旅行をしていた「私」は鎌倉に来ていた「先生」と出会い交流を始め東京に帰った後も先生の家に出入りするようになる。先生は奥さんと静かに暮らしていた。先生は私に何度も謎めいた、そして教訓めいたことを言う。私は、先生に過去を打ち明けるように迫ったところ来るべき時に過去を話すことを約束した。'); 4。mecabで分かち書きした、「夏目」「漱石」をスペースで区切った文字で検索   っがしかし、検索結果が帰ってこない 実行してみたSQL   select * from book where match( search_word ) against( '夏目 漱石' IN BOOLEAN MODE);   select * from book where match( search_word ) against( '+夏目 +漱石' IN BOOLEAN MODE);   select * from book where match( search_word ) against( '"夏目 漱石"' IN BOOLEAN MODE);   select * from book where match( search_word ) against( '"+夏目 +漱石"' IN BOOLEAN MODE);   select * from book where match( search_word ) against( '"+夏目 +漱石"' IN BOOLEAN MODE);   select * from book where match( search_word ) against( '"*夏目 *漱石"' IN BOOLEAN MODE);   select * from book where match( search_word ) against( '"*夏目* *漱石*"' IN BOOLEAN MODE);   「夏目漱石」とひとくくりにした文字列で検索すると、レコードが帰ってきます    また、against( 'natsume souseki' IN BOOLEAN MODE); も帰ってきます 実際にやってみたいことは、上記の文章で「先生」「鎌倉」「私」「夏目」の4語で検索すると 上記のレコードが帰ってくるということがやりたいですのですが、 select * from book where match( search_word ) against( '夏目 先生 鎌倉 私' IN BOOLEAN MODE); のSQLや対象文字列に+や*を付けたものを実行しても引っかかりませんでした。 私が行った設定/sqlに不備がございましたらご指摘/ご指導いただけませんでしょうか。 よろしくお願いいたします。