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

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

ただいまの
回答率

90.34%

サイトない検索

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 692

shaobao

score 31

今回、サイト内「鈴木 スポーツ」検索ワードで検索すると検索データが出るようなプログラムを作りたいです。

DBから参照すること。

テーブル'topic','user','grop'3つテーブルがあります。
それぞれ、nameとtagフィールドがあります。

この3つテーブル中nameとtagフィールドからキーワードを参照する

現状、下記のようなコードを書きましたが、検索結果0件です。

if($_POST["search"]):
    $_SESSION["res"] = array();
    $where = " WHERE 1 AND";
    $kensaku = htmlspecialchars($_POST['search']);
    $kensaku = trim($kensaku);
    $word = str_replace(" ", " ", $kensaku);
    $word = str_replace("'", "\'", $word);
    $words = preg_split("/[ ]+/",$word);
    $count = count($words);
else:
    if($_GET["tag"]):
        $_SESSION["res"] = array();
        $where = " WHERE 1 AND";
        $kensaku = htmlspecialchars($_GET["tag"]);
        $kensaku = trim($kensaku);
        $word = str_replace(" ", " ", $kensaku);
        $word = str_replace("'", "\'", $word);
        $words = preg_split("/[ ]+/",$word);
        $count = count($words);
    else:
        $err = "検索タグワードが入力されていません";
    endif;
endif;
//topicから検索
$db->tbl_name = "topic";
if($count == 1):
    //入力文字が1つの場合
        $img_topic = $db->Asearch("tag" , $words[0]);
    else:
    //入力文字が複数あった場合
        $where .= " `tag` LIKE '%" . $words[0] . "%'";
        if($count > 1):
            for($i = 1; $i < $count; $i++):
                $where .= " AND `tag` LIKE '%" . $words[$i] . "%'";
            endfor;
        endif;
        $table = "topic";
$sql="SELECT *
    FROM `{$table}`
    {$where}";
        $topic = $db->get_query($sql);
endif;
//userから検索
$db->tbl_name = "user";
if($count == 1):
    //入力文字が1つの場合
        $img_topic = $db->Asearch("tag" , $words[0]);
    else:
    //入力文字が複数あった場合
        $where .= " `name` LIKE '%" . $words[0] . "%'";
        if($count > 1):
            for($i = 1; $i < $count; $i++):
                $where .= " AND `name` LIKE '%" . $words[$i] . "%'";
            endfor;
        endif;
        $table = "user";
$sql="SELECT *
    FROM `{$table}`
    {$where}";
        $user= $db->get_query($sql);
endif;

//gropから検索
$db->tbl_name = "grop";
if($count == 1):
    //入力文字が1つの場合
        $img_topic = $db->Asearch("tag" , $words[0]);
    else:
    //入力文字が複数あった場合
        $where .= " `tag` LIKE '%" . $words[0] . "%'";
        if($count > 1):
            for($i = 1; $i < $count; $i++):
                $where .= " AND `tag` LIKE '%" . $words[$i] . "%'";
            endfor;
        endif;
        $table = "grop";
$sql="SELECT *
    FROM `{$table}`
    {$where}";
        $grop= $db->get_query($sql);
endif;
・
・
・
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

0

LIKEをAND条件にしているからでは。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/11 13:28

    一応、OR条件に変更して確認しても結果0件です。
    鈴木だけで検索したら、結果一覧が表示され、スポーツだけで検索したら、結果一覧も表示される。

    キャンセル

  • 2016/07/11 13:39

    気になった点。

    ・$whereを初期化していないのでWHEREを生成するところで初期化する
    $where = ""; ←追加
    $where .= " `tag` LIKE '%" . $words[0] . "%'";

    ・$sqlを生成しているところの最終行にセミコロンがないのはコピペミスでしょうか。
    $sql="SELECT *
    FROM `{$table}`
    {$where}" ← ここ

    ・「nameとtagフィールドからキーワードを参照する」という割に、LIKEの対象がtagだけだったりするのは仕様でしょうか。

    キャンセル

  • 2016/07/11 13:42 編集

    追加。
    3回クエリを発行しているが、全て結果の格納先が$img_topicなので、最後のクエリしか意味がないような。

    キャンセル

  • 2016/07/11 18:38

    ttyp03さん

    この度、ご回答いただきまことにありがとうございます。
    大変参考になりました。
    ありがとうございました。

    キャンセル

0

「鈴木 スポーツ」は・・・

  • 「鈴木」もしくは「スポーツ」を含むor検索なのか
  • 「鈴木」かつ「スポーツ」を含むand検索なのか、
  • 「鈴木 スポーツ」に完全一致なのか

によって書き方がかわります

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/11 13:19

    コメントありがとうございます。
    「鈴木」もしくは「スポーツ」を含むor検索
    部分一致にしたいです。

    キャンセル

  • 2016/07/11 13:32

    LIKEが煩雑で面倒であればREGEXPでもいいかも

    WHERE topic REGEXP '鈴木|スポーツ' OR user REGEXP '鈴木|スポーツ' OR grop REGEXP '鈴木|スポーツ'

    キャンセル

  • 2016/07/11 18:42

    yambejpさん

    ご回答ありがとうございます。
    ご参考させて頂きます。
    ありがとうございました。

    キャンセル

0

$img_topic = $db->get_query($sql);

これがテーブルごとに使われてますが、上書きしているだけなのでは?
最後のしか意味がない気がします。

どういったテーブル構造なのかわからないので、JOINできるのかわかりませんが、
できるなら、JOINして、クエリの発行は1回にしたほうがいいのではないでしょうか?

例えば

SELECT t.*, u.*, g.*
  FROM topic t
  LEFT JOIN user u ON t.id = u.id
  LEFT JOIN grop g ON t.id = g.id
 WHERE CONCAT(t.name, t.tag, u.name, u.tag, g.name, g.tag) LIKE '%鈴木%'
    OR CONCAT(t.name, t.tag, u.name, u.tag, g.name, g.tag) LIKE '%スポーツ%'


・・・とか。
クエリは未検証です。エラー出たらごめんなさい。

あと$_POST["search"]は入力文字ですから、セキュリティ対策として、bindを使ってクエリを発行するようにしたほうがいいですよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/11 18:41

    otomさん

    この度、ご回答いただきまことにありがとうございます。
    別の方から、より参考になったため、問題解決になりました。

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

    キャンセル

0

少しご質問からずれると思いますが
Like検索よりMySQL(InnoDB)でしたらFullTextSearchを使った方がずっと早いです。
データが貯まれば貯まるほどLikeでは辛くなります(サーバーが)
https://dev.mysql.com/doc/refman/5.6/ja/fulltext-search.html

上記を踏まえるて言いますと、
前準備:
summaryテーブルと作るとします。
id, table_id, name_tag, tableのname_tagカラムにFullTextインデックスをはります。

'topic','user','grop'のInsert or Updateする際にsummaryにもInsert or Updateを行い、
検索する際にsummaryテーブルのname_tagから検索し、引っかかったtableとtable_idから対象のデータをひくというのはどうでしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/11 18:40

    mtyさん

    ご回答ありがとうございます。
    ご参考させて頂きます。

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

    キャンセル

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

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る