• ベストアンサー

2つフィールドを連結して検索するには

MySQLの初心者です。よろしくお願いします。 1つのテーブルにある2つのフィールドのうち、どちらかにキーワードが入っている場合(両方に入っている場合も含む)を抽出したいのですが、検索するキーワードが1個の場合は、下記のようにすれば、うまく動くのですが、 ●1個のキーワードで検索する場合 (例として、2つのフィールドのうちどちらかに「山」のキーワードが入っている場合を抽出) select * from table WHERE (item_name LIKE "%山%" or outline LIKE "%山%" ) ●テーブルの内容(テーブル名:table) item_name | outline ==========+========= 山がある + 山と川 ----------+---------- 山がある + 川と森 ----------+--------- 山がある + 谷と林 --------------------- 質問したいことは、上記のテーブルから、item_nameとoutlineのフィールドのうち、2つのキーワード「山」と「川」が両方含まれるレコードを抽出したいです。上記のテーブルでいうと、抽出の結果、1行目と2行目が抽出したいのです。 ちなみに、下記のように記述したら、上記のテーブルで1行目だけ抽出されます。 select * from table WHERE (item_name LIKE "%山%" and item_name LIKE "%川%" or outline LIKE "%山%" and outline LIKE "%川%" ) 他にも、下記のように試してみたのですが、うまく抽出できませんでした。 SELECT * FROM table WHERE (concat(item_name,outline) LIKE '%山%' and concat(item_name,outline) LIKE '%川%') item_nameとoutlineのフィールドを結合して、結合した文字列で、「山」と「川」の両方が入っているレコードを抽出する方法はありますか? 2つのフィールドの文字列をあわせたなかから、「山」と「川」のキーワードが両方含まれるレコードを抽出したいのですが、何かよい方法はありますでしょうか。ご回答よろしくお願いいたします。

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

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

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

まず第一に、'%山%'というような書き方は、インデックスがまっとうに きかないので、高速化は期待できせん。 またCONCATしたものに対する検索もインデックスが利きません。 よって処理としてはできるけど、SQLらしくない処理だという前提で ご理解ください。 あとサンプルとはいえテーブルにtableという名前をつけるのは いただけません。混乱の元なので注意ください。そのうえで例示の・・・ SELECT * FROM yamakawa_table WHERE CONCAT(item_name,outline) LIKE '%山%' AND CONCAT(item_name,outline) LIKE '%川%' ってやりましたが、特に問題なさそうですが・・・ これは条件が片方ならヒットするということですか? バージョンによっては日本語検索の精度にバラつきがあるので そのせいかもしれませんね なお、ホントはだめなんですが、上記のSQLを以下のように書いても 同じ結果になるようです。 SELECT *,concat(item_name,outline) AS K FROM yamakawa_table HAVING (K LIKE '%山%' AND K LIKE '%川%') (しつこいようですが、ホントはだめなんですよー) 効率は変わりませんが考え方としてはこんな感じでもいけそうです SELECT * FROM yamakawa_table WHERE (item_name LIKE '%山%' OR outline LIKE '%山%')+(item_name LIKE '%川%' OR outline LIKE '%川%') >=2

flaflasan
質問者

補足

ご回答いただき、ありがとうございました。 テーブル名に関しまして、教えていただき、今後気をつけます。 バージョンによって、日本語検索の制度にバラつきとのことで、違うバージョンで試してみました。 利用しているレンタルサーバーが、2つのバージョンのMySQLを利用できる環境にありますので、MySQL 4.0.26でやってみたら、うまくいきませんでしたが、MySQL 5.0.51のほうで、同じようにやってみましたら、うまく検索できました。 ありがとうございました。 それから、CONCATを利用したものもインデックスがきかないとありましたが、同じ内容のものをSQLらしく書く方法がありましたら、ご回答いただければと思います。 よろしくお願いいたします。

その他の回答 (2)

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

>同じ内容のものをSQLらしく書く方法がありましたら 実は構造的にいじらないと無理なんですよ、ちょっとレベルが高い処理 になるので、いまはまだ時期尚早かもしれませんね SQLで高速にLIKEがつかえるのは前方一致か後方一致のいずれか、 すなわちLIKE '山%'かLIKE '%山'のどちらかしか有効ではありません。 (遅くてもいいならご提示の方法でもいけます) もしやるなら・・・kakasiなどで分かち書きをして全文検索するとか、 キーワードを別途専用にテーブルで管理するとかいろいろ手間がかかります。

flaflasan
質問者

お礼

いろいろと教えていただき、ありがとうございました。 感謝いたします。 まだまだ初心者なので、これからいろいろ勉強していきたいと思います。 ありがとうございました。

  • masa6272
  • ベストアンサー率66% (93/140)
回答No.2

行数の多いテーブルでは、SQLでの全文検索は効率が悪くなります。 英語だと、単語単位の検索を高速にするインデックスをテーブルに貼れますが・・・ とはいっても、必要な場合はありますね。こんなのはどうでしょう? SELECT * FROM a WHERE concat(item_name,outline) REGEXP '山.*川|川.*山';

flaflasan
質問者

お礼

ご回答いただき、ありがとうございました。 教えていただいた方法で、うまく検索することができました。 いろいろ勉強になり、感謝いたします。

関連するQ&A

  • 文字の検索について

    「test」というデータベースの「shouhin」というフィールドに、次のようなレコードがあった場合、「PHP」というキーワードと「本」というキーワードの両方にマッチしたレコードを抽出したいのですが、自分で試した方法は、下記の2つの方法なのですが、この方法では、マッチさせるキーワードが3個の場合4個の場合を考えると式が複雑になってしまいます。 今やりたいことは、たとえば、googleでの検索のように、「PHP 本」と入力したら、PHPと本の両方のキーワードを含んだレコードを抽出したいのです。「PHP 本 楽しい」なら、この3つのキーワードを含んだレコードといった感じに。 検索したいキーワードを変数(たとえば、$keyword='PHP 本')にいれておいて、これを簡単に実現するsqlの記述の仕方はありますか? ご回答よろしくお願い致します。 ●「test」というデータベースの「shouhin」というフィールドに対して検索 ID |shouhin --+---------- 1 | PHPが書かれた本 2 | この本はPHPが書かれています 3 | 楽しいPHPの本 4 | HTMLの本 --+--------------------------- ●試してみた方法2種類 SELECT * FROM `test` WHERE shouhin REGEXP '(アジアン.*テーブル)|(テーブル.*アジアン)' SELECT * FROM `test` WHERE shouhin LIKE '%アジアン%' and shouhin_name LIKE '%テーブル%'

  • アクセス 同じフィールド(テキスト型)のレコードを連結させたい

    お世話になります。アクセスの超初心者です。 数値型であれば同じ列の合計できますが、テキスト型で以下のように 連結できる方法がございませんでしょうか? <元テーブル> レコード番号  列:キーワード(テキスト型)  列:抽出条件   1      "山,川"                AAA   2      "海外,国内"             AAA   3      "熊,馬"                BBB   ↓このテーブルを元にクエリをかける <クエリ出力結果> 列:抽出条件にAAAを指定   列:キーワードの合計(連結)   "山,川、海外,国内"       ^^      ↑連結の境目には"、"などの区切りを入れたい。 宜しくお願い致します。

  • AccessのクエリでvbLfのみ抽出するには

    Access2010のクエリー(SQL)で vbLfかvbCrLfが含まれているレコードを抽出するには、 SELECT [テーブル1].* FROM テーブル1 WHERE [テーブル1].フィールド1 Like "*" & Chr(10) & "*"; vbLfが含まれているレコードは抽出せず、 vbCrLfが含まれているレコードだけを抽出するには、 SELECT [テーブル1].* FROM テーブル1 WHERE [テーブル1].フィールド1 Like "*" & Chr(13) & Chr(10) & "*"; でよいと思いますが、 vbCrLfが含まれているレコードは抽出せず、 vbLfが含まれているレコードだけを抽出するには、 どのように記述すればよいのでしょうか。 よろしくお願いします。

  • MySQL 複合検索条件

    MySQLでひとつのテーブルの複数フィールドに値を設定してレコードを参照したい。 例えば、key-field-1 >= ??? と key-field-2 >= ???で key-field-1は主キーでkey-field-2は従属キーとし、key-field-1の条件に合うレコードで、次にkey-field-2の条件に合うレコードを見つけ、それ以降の全てのレコードを抽出したい。 select * from table-1 where key-field-1 >= ??? and key-field-2 >= ??? で検索すると 両方の条件を満たすレコードのみ検索される。 アドバイスを待っています。

  • MySQLで検索されたフィールド

    いつもお世話になっております。 MySQLで以下のようなSQL文を発行しています。 select * from table where (INSTR(`table`.`name`,'キーワード')<>0 OR INSTR(`table`.`keyword`,'キーワード')<>0) nameカラムとkeywordカラムのどちらのカラムから検索されたのか知りたいのですが どのようにしたらよろしいでしょうか。 (「キーワード」文字列がどちらのカラムに入っているのか知りたいです。) [環境]  MySQL:5.5.16 よろしくご教示お願いいたします。

    • ベストアンサー
    • MySQL
  • 別のテーブルのフィールドを抽出項目にするには?

    別のテーブルのフィールドを抽出項目にするには? Access初心者です。 申し訳ありませんが、急ぎ回答いただきたく思います。 どうか宜しくお願いいたします。 お伺いしたい内容は、 データが多く、抽出条件も多いので、 別のテーブルのフィールドに入っている単語を使い、 抽出したい元データのレコードをあいまい検索して非表示にしたいです。 データの内容は下記になります。 --------------------------------------- 元データ(テーブル1とテーブル2から結合したクエリ(名前は元データ) フィールド1 フィールド2 ID-1     りんご ID-2     バナナ ・       ・ ・       ・ ・       ・ ID-2000    チェリー --------------------------------------- --------------------------------------- 除外リスト(テーブル3。名前は除外リスト) フィールド1 りんご チェリー ・ ・ ・ --------------------------------------- 元データのフィールド2に Not Like "*りんご*" And Not Like "*チェリー*" と記述すれば、フィールド2にりんご、チェリーを含むレコード以外のものが表示され、 欲しい情報が手に入るのですが、(上記例だとバナナのみ表示される) 実際にはりんご、チェリーなどあいまい検索し、非表示にしたいキーワードが100個あります。 なので、除外リストというテーブルをつくり、 そのフィールド内に書かれたキーワードを使い Not Like "*りんご*" And Not Like "*チェリー*" と同じような表示結果になるようにしたいのですが、 やり方が調べてもどうしてもわかりません。 どうか皆様のお力を貸してください。 宜しくお願いいたします。

  • MySQL:一つを除いてすべてのフィールドを選択

    こんにちは、 データベースにはTABLE1とTABLE2の二つのテーブルがあって、TABLE1からTABLE2に、一つのフィールドを除いてほかのすべてのフィルードを移すには、どうすればいいのでしょうか INSERT INTO TABLE2 SELECT * FROM TABLE1 WHERE field_name != ID みたいなものがないのでしょうか IDフィールド以外にほかのすべてのフィールドを移したい。 TABLE 2の構造は IDフィールド COL2 COL3 COL4 ... COL50 つまりCOL2からCOL50までのデータを移したいのですが、できればフィールドを一つ一つ書くのを避けたいのです。 詳しい方がいらっしゃいましたら。ご回答をよろしくお願いします。

    • ベストアンサー
    • MySQL
  • ACCESSの複数フィールドの検索

    私がしたい事はおそらくかなり初歩的なことと類推されますので、がっくりされないようにお願いします。 「報告書」のテーブルがあります。 その報告書のフィールドは 報告日 報告者氏名 A店の感想 B店の感想 C店の感想 となっていると考えてください。 このテーブルをもとに、表形式で一覧の出るフォームを作っており、この一覧のフォームフッターにテキストボックスがあります。 このテキストボックスに例えば「D商品」と入力してエンターを押すと「A店の感想 B店の感想 C店の感想」中に「D商品」が出てくるレコードすべてが抽出されるというようにしたいと思っています。 1つのフィールドでのやり方がとあるサイトにあったので、私は Private Sub テキスト28_AfterUpdate() Me.Filter = "A店の感想 like'*" & Me!テキスト28 & "*'" Me.FilterOn = True End Sub という式を作成しました。 これだと「A店の感想」フィールドにキーワードがあればヒットしますが、B店、C店にキーワードがあってもA店にキーワードが無ければ反応はありません。 これを3つのフィールドで出来るようにいくつか試してみましたがどれも失敗でした。 どのようにすれば、複数フィールドのキーワード検索・抽出が出来るのでしょうか。 私の取ったやり方に近いもの、別の全然違うやり方、ともに勉強になるので色々教えてください。 それと、これでも結構検索したのですが、検索ワードが不適切なのか、ありそうなニーズにも関わらずぴったりくるものを見つけられませんでした。 もしよければACCESSをわかりやすく学習出来るサイトを教えてください。有名そうなところをいくつかは知っております。

  • MYSQLで全てのカラムから検索する。

    tbというテーブルのbangというカラムに4が含まれていれば表示というのは select * from tb where (bang) like '%4%' ; という形になりますが、このtbテーブルにさらにname,tukiというカラムがあったとして カラムに関係なくレコードのどこかに4が入っていれば抽出するというSQL文が書きたいです。 select * from tb where bang like '%4%' or name like '%4%' or tuki like '%4%' ; と書くことで何とか今まではやってきたのですが、カラム数が増えてきてしまったので、ものすごく長いSQL文なってしまいました。 もう少しスマートにする方法はありませんか?

    • ベストアンサー
    • MySQL
  • ワイルドカードの検索

    項目に'%'が入力されているデータを抽出したいのですが、 以下のようなSQLだとデータがすべて抽出されていまいます。  SELECT *   FROM t_table  WHERE code_name LIKE '%%%' '%'を検索するにはどうのようにすればいいのでしょうか?