PHPとMYSQLについて質問です。


現在、PHPの画面から検索ワードを入力して、その検索キーワードを元に
SQLでLIKE検索を行っているのですが、自分の考えているものがうまくできず困っております。

やりたいことは2つや3つの検索ワードを元に必要データを抽出するというものです。

例えば

テーブル TEST
項目 BRAND
   PRODUCT

項目BRANDにはブランド名が PRODUCTには商品名が入っています。

PHPのテキスト入力画面に ブランド名 商品名 を検索ワードとして入力して、
検索ボタンを押すと、項目BRANDとPRODUCTの両方から検索ワードに含まれる商品データを抽出してくれるようにしたいです。

例)BRANDにコムサ PRODUCTにマフラー と入っているものを探したいとして

検索テキストに コムサ マフラー と入力すると BRANDにコムサ PRODUCTにマフラー とはいっているものを抽出出来るようにしたいです。

このようなことをLIKE検索ですることは可能でしょうか?

わかるかたおりましたらよろしくお願いいたします。

回答の条件
  • 1人2回まで
  • 登録:2009/12/15 02:43:52
  • 終了:2009/12/15 13:36:38

ベストアンサー

id:kn1967 No.1

kn1967回答回数2915ベストアンサー獲得回数3012009/12/15 05:38:38

ポイント100pt

>コムサ マフラー と入力すると BRANDにコムサ PRODUCTにマフラー


並び順で必ず一つ目の単語がブランド名で二つ目が商品名だと、

決め付けても良いのであれば、

<?php
$text = "コムサ    マフラー"; // 入力されたテキスト
$textArray = preg_split("/ /", preg_replace("/( | )+/", " ",  trim($text))); // 分割
$sqlStr = "SELECT * FROM test WHERE (brand Like '%$textArray[0]%') AND (product Like '%$textArray[1]%')"; // SQL生成
echo $sqlStr; // テスト出力
?>

のような具合に単純に分割してしまえばよいのが、これで良いのだろうか?

例えば、「コムサ マフラー 手袋」などと入れた場合は、

単純に「手袋」が無視されるだけで済むかもしれないけど、

検索ボックスに「マフラー コムサ」の順番で入れた場合はどうですか?

結果がゼロ件になるわけだけど、それで良いということであれば、

以下は読まなくても結構です。


ブランド名用のテキスト欄と、商品名用のテキスト欄を用意しておいて、

必要に応じて片方もしくは両方を入力するという方法が無難だと思うが、

どうなのだろうか?

下記は少し凝って、それぞれ複数のテキストに対応してますが、もちろん、

上記と同様に単純にしてもかまいません。

<?php
$textBrand = "コムサ ヴィトン"; // 入力されたテキスト
$textProduct = "マフラー 手袋 カバン"; // 入力されたテキスト
$textBrandArray = preg_split("/ /", preg_replace("/( | )+/", " ", trim($textBrand))); // 分割
$textProductArray = preg_split("/ /", preg_replace("/( | )+/", " ", trim($textProduct))); // 分割
$sqlStr = ""; // 初期化
if ($textBrandArray[0] != "" and $textProductArray[0] != "") { // 両方入力されている場合のSQL生成
    $sqlStr = "SELECT * FROM test WHERE "
            . "((brand Like '%" . join("%') OR (brand Like '%", $textBrandArray) . "%')) AND "
            . "((product Like '%" . join("%') OR (product Like '%", $textProductArray) . "%'))"
        ;
} elseif ($textBrandArray[0] != "") { // ブランドだけ入力されている場合のSQL生成
    $sqlStr = "SELECT * FROM test WHERE "
            . "(brand Like '%" . join("%') OR (brand Like '%", $textBrandArray) . "%')"
        ;
} elseif ($textProductArray[0] != "") { // 商品だけ入力されている場合のSQL生成
    $sqlStr = "SELECT * FROM test WHERE "
            . "(product Like '%" . join("%') OR (product Like '%", $textProductArray) . "%')"
        ;
} else {
    echo "エラー!ブランド名も商品名も入力されていません。";
}
echo $sqlStr;
?>

※いずれも単体で動きますので、まずはどのようなSQLが生成されるか、

 そして、どのようにプログラムが動いているかをよく確認してから、

 ご自身のシステムに組み込むようにしてください。

id:aiomock

ご回答ありがとうございます。是非試してみます^^。

2009/12/15 12:44:26

その他の回答(1件)

id:kn1967 No.1

kn1967回答回数2915ベストアンサー獲得回数3012009/12/15 05:38:38ここでベストアンサー

ポイント100pt

>コムサ マフラー と入力すると BRANDにコムサ PRODUCTにマフラー


並び順で必ず一つ目の単語がブランド名で二つ目が商品名だと、

決め付けても良いのであれば、

<?php
$text = "コムサ    マフラー"; // 入力されたテキスト
$textArray = preg_split("/ /", preg_replace("/( | )+/", " ",  trim($text))); // 分割
$sqlStr = "SELECT * FROM test WHERE (brand Like '%$textArray[0]%') AND (product Like '%$textArray[1]%')"; // SQL生成
echo $sqlStr; // テスト出力
?>

のような具合に単純に分割してしまえばよいのが、これで良いのだろうか?

例えば、「コムサ マフラー 手袋」などと入れた場合は、

単純に「手袋」が無視されるだけで済むかもしれないけど、

検索ボックスに「マフラー コムサ」の順番で入れた場合はどうですか?

結果がゼロ件になるわけだけど、それで良いということであれば、

以下は読まなくても結構です。


ブランド名用のテキスト欄と、商品名用のテキスト欄を用意しておいて、

必要に応じて片方もしくは両方を入力するという方法が無難だと思うが、

どうなのだろうか?

下記は少し凝って、それぞれ複数のテキストに対応してますが、もちろん、

上記と同様に単純にしてもかまいません。

<?php
$textBrand = "コムサ ヴィトン"; // 入力されたテキスト
$textProduct = "マフラー 手袋 カバン"; // 入力されたテキスト
$textBrandArray = preg_split("/ /", preg_replace("/( | )+/", " ", trim($textBrand))); // 分割
$textProductArray = preg_split("/ /", preg_replace("/( | )+/", " ", trim($textProduct))); // 分割
$sqlStr = ""; // 初期化
if ($textBrandArray[0] != "" and $textProductArray[0] != "") { // 両方入力されている場合のSQL生成
    $sqlStr = "SELECT * FROM test WHERE "
            . "((brand Like '%" . join("%') OR (brand Like '%", $textBrandArray) . "%')) AND "
            . "((product Like '%" . join("%') OR (product Like '%", $textProductArray) . "%'))"
        ;
} elseif ($textBrandArray[0] != "") { // ブランドだけ入力されている場合のSQL生成
    $sqlStr = "SELECT * FROM test WHERE "
            . "(brand Like '%" . join("%') OR (brand Like '%", $textBrandArray) . "%')"
        ;
} elseif ($textProductArray[0] != "") { // 商品だけ入力されている場合のSQL生成
    $sqlStr = "SELECT * FROM test WHERE "
            . "(product Like '%" . join("%') OR (product Like '%", $textProductArray) . "%')"
        ;
} else {
    echo "エラー!ブランド名も商品名も入力されていません。";
}
echo $sqlStr;
?>

※いずれも単体で動きますので、まずはどのようなSQLが生成されるか、

 そして、どのようにプログラムが動いているかをよく確認してから、

 ご自身のシステムに組み込むようにしてください。

id:aiomock

ご回答ありがとうございます。是非試してみます^^。

2009/12/15 12:44:26
id:pah00 No.2

pah00回答回数208ベストアンサー獲得回数52009/12/15 08:33:07

ポイント35pt

BRAND like '%コムサ%' OR PRODUCT like '%マフラー%'

/////

ORよりANDがよければANDで。

id:aiomock

ご回答ありがとうございます。

2009/12/15 12:44:44
  • id:aiomock
    kn1967 さん

    プログラム実行出来ました。ご回答ありがとうございます^^。

    3つ以上の時のやり方も教えていただきありがとうございます。

    今回ですが、一つのテキストボックスに データを入力してのことだったのですが、

    3つ以上入っていた場合 スペースで分割して

    コムサ マフラー 手袋 と入力した場合

    ブランド(BRAND)項目で コムサ マフラー 手袋 を含むもの

    商品(PRODUCT)項目で コムサ マフラー 手袋 を含むものを SELECT する。

    とすることは可能でしょうか?

    4つ、5つの場合も同様にしたいのですが可能でしょうか?

    私の理解不足があると思いますが、ご回答いただければよろしくお願いいたします。
  • id:kn1967
    こんな感じ。
    数に関しては元々から制限してませんので、環境の許す限り、
    4つや5つどころか10でも20でも同じように動くように作ってありますから、
    入力されたテキストの中身を適当に増やしてみてください。

    $text = "コムサ マフラー 手袋"; // 入力されたテキスト
    $textArray = preg_split("/ /", preg_replace("/( | )+/", " ", trim($text))); // 分割
    $sqlStr = ""; // 初期化
    if ($textArray[0] != "") {
    $sqlStr = "SELECT * FROM test WHERE "
    . "((brand Like '%" . join("%') OR (brand Like '%", $textArray) . "%')) AND "
    . "((product Like '%" . join("%') OR (product Like '%", $textArray) . "%'))"
    ;
    } else {
    echo "エラー!ブランド名も商品名も入力されていません。";
    }
    echo $sqlStr;
  • id:aiomock
    kn1967 さん

    ご回答ありがとうございます。
    実行してみました。

    3つ、4つに増やしてみたのですが、最初の条件しか抽出しないみたいです。。

    コムサ ネクタイ マフラー と入力したら コムサ ネクタイ のみ抽出。
    マフラーは抽出しない。

    という風になっております。

    お手数をおかけしますが、一度見ていただければと思います。

    今の状態でもとても満足なのですが、、。お手数おかけします。。。


  • id:kn1967
    どのようなSQLが出力されてきましたか?
    こちらでもコメント欄に記載したもので単体テストしてみたところ、
    SELECT * FROM test WHERE
    ((brand Like '%コムサ%') OR (brand Like '%ネクタイ%') OR (brand Like '%マフラー%')) AND
    ((product Like '%コムサ%') OR (product Like '%ネクタイ%') OR (product Like '%マフラー%'))
    という結果になりました。長いので改行してますが、同じになりました?


    WHERE句の意味は
      brand にコムサ/ネクタイ/マフラー のいずれかが含まれており、
    なおかつ
      product にもコムサ/ネクタイ/マフラー のいずれかが含まれているもの。
    となっています。


    すでに、本番環境で実際にデータを引き出すように改造してあるのならば、
    データのほうを再確認してみてください。
    例えば、長音記号(ー)が全角マイナス(-)になってたりとかはよくあります。
      $text = "コムサ ネクタイ マフラー"; // 入力されたテキスト
    ではなくて
      $text = "マフラー"; // 入力されたテキスト
    でやったらどうなるかなどもテストしてみてください。
      $text = "マフラ-"; // 入力されたテキスト
    でもテストしてみてください。
  • id:aiomock
    ご回答ありがとうございます。

    データベース内の環境で

    SELECT * FROM test WHERE
    ((brand Like '%コムサ%') OR (brand Like '%ネクタイ%') OR (brand Like '%マフラー%')) AND
    ((product Like '%コムサ%') OR (product Like '%ネクタイ%') OR (product Like '%マフラー%'))

    を実行したところ、きちんと3商品に一致するものを抽出することができました。

    しかし、PHP画面上で入力して検索をすると、

    コムサ ネクタイ マフラー

    は、やはり最初に入力したもの コムサ ネクタイ しか抽出をしてくれない状況になっています。

    結果が一致しない状況と現在なっております。

    データのほうも確認し、-を含まない商品でも検索をしかけてみましたが、やはりPHP画面では同じような現象が起こってしまいます。。。

  • id:kn1967
    実装したプログラムのほうでecho出力して、
    本当にテストプログラムと同じSQLが生成できているかを確認してみてください。

    何度もしつこく言いますけど、
    Debug.Print や echo は忘れずやってくださいね。

    余談ですが、VBAの最新質問のチェックボックスとラジオボタンは、
    フォームタグのnameかidが必要なので書き込んでおいてくださいね。
    (この二つはnameじゃ操作できないんですよ。)
  • id:kn1967
    訂正、フォームタグいらなかったです。
    もう少し確認したら、あちらのほうは投稿しようと思ってます。
    (他に回答がついていなければですが・・・。)
  • id:aiomock
    kn1967 さん

    お手数をおかけします。

    実行出来ました。

    echo で問題を探っていったところ解決できました。

    SQL命令文を mysql() でくくっていなかったことが問題です。

    ちょんぼミスで本当に恥ずかしい限りです。。

    お手数をおかけし申し訳ありません。。

    実際に出来上がった機能を付け加えてみたのですが、大変いいものに出来上がりましたので

    本当に感謝しております。

    ありがとうございます。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません