14

コンマ区切りのキーワードを含む文字列があります。例えば:

$keywords = 'keyword1, keyword2, keyword3';

名前が付けられた私のテーブルスキーマtbl_addressは次のようになります(簡略化):

id        INT(11)        PRIMARY KEY, AUTO INCREMENT
address   VARCHAR(250)   NOT NULL

MySQLiPHPで使用する必要があるとします(ではないPDO)。

これが私の現在のアプローチです:

$result = array();
$keyword_tokens = explode(',', $keywords);
foreach($keyword_tokens as $keyword) {
  $keyword = mysqli_real_escape_string(trim($keyword));
  $sql = "SELECT * FROM tbl_address WHERE address LIKE'%$keyword%'";
  // query and collect the result to $result
  // before inserting to $result, check if the id exists in $result.
  // if yes, skip.
}
return $result;

このアプローチは機能しますが、パフォーマンスが非効率的です。キーワードが多い場合、多くのクエリが作成されます。

私の質問は、同じ目標を達成するためのより良い方法はありますか? つまり、キーワードの ANY を含むアドレスを持つすべてのレコードを返す最も簡単な方法は何ですか?

4

8 に答える 8

29

シンプルなREGEXPものがあなたの求めているものかもしれません。どれだけ効果があるかは自分で確かめる必要があります。

SELECT * FROM tbl_address WHERE field REGEXP 'keyword1|keyword2|keyword3';

于 2013-04-16T10:31:36.813 に答える
5
 SELECT * FROM user;
 +---------+----------+
 | user_id | username |
 +---------+----------+
 |     101 | Adam     |
 |     102 | Ben      |
 |     103 | Charlie  |
 |     104 | Dave     |
 +---------+----------+

 SELECT * 
   FROM user 
  WHERE FIND_IN_SET(username,'adam,ben,dave') > 0;
 +---------+----------+
 | user_id | username |
 +---------+----------+
 |     101 | Adam     |
 |     102 | Ben      |
 |     104 | Dave     |
 +---------+----------+
于 2013-04-16T10:18:39.490 に答える
3

「OR」のみが必要で、他には何もありません...

<?php

$result = array();
$keyword_tokens = explode(',', $keywords);
$keyword_tokens = array_map('mysqli_real_escape_string', $keyword_tokens);

$sql = "SELECT * FROM tbl_address WHERE address LIKE'%";
$sql .= implode("%' or address LIKE '%", $keyword_tokens) . "'";

// query and collect the result to $result
// before inserting to $result, check if the id exists in $result.
// if yes, skip.

return $result;

編集:キーワードもトリムするようにしてください

<?php

$result = array();
$keyword_tokens = explode(',', $keywords);
$keyword_tokens = array_map(
    function($keyword) {
        return mysqli_real_escape_string(trim($keyword));
    }, 
    $keyword_tokens
);

$sql = "SELECT * FROM tbl_address WHERE address LIKE'%";
$sql .= implode("%' OR address LIKE '%", $keyword_tokens) . "'";

// query and collect the result to $result
// before inserting to $result, check if the id exists in $result.
// if yes, skip.

return $result;

また、db リソース リンクもmysqli_real_escape_string()関数に渡す必要があります...

于 2013-04-16T10:22:41.553 に答える
1

WHERE IN 句を試してください:

$keyword = (array)explode(',', $keywords);
for($i=0;$i=count($keyword);$i++){
   $keyword[$i]=mysqli_real_escape_string(trim($keyword[$i]),'\'" ');
}
//This is what I suggest.
$query='SELECT * FROM tbl_address WHERE address IN ("'.implode('","',$keyword).'")';

MySQL 5.1 で正常にテストされました。

于 2015-01-11T15:28:28.210 に答える
1

単一のクエリを作成

$keywordary = explode(',', $keywords);
foreach($keywordary as $keyword) {
  $keys = trim($keyword);
    $other .=" or address like '%$keys%'";
}
$sql = "SELECT * FROM tbl_address WHERE address LIKE'%$keyword%' $other";

execute query;
return $result;
于 2013-04-16T10:28:18.590 に答える
1

最良の方法は、全文検索を使用することです。

http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

フルテキストを使用したくない場合は、WHERE 条件で OR を使用できます

SELECT * FROM tbl_address WHERE address LIKE '%$keyword%' OR adress LIKE '%$keyword2%'
于 2013-04-16T10:16:56.777 に答える
0

こんにちは、ユニオンを使用してクエリを作成し、ループの最後で実行します

$result = array();
$keyword_tokens = explode(',', $keywords);
$sql = '';
foreach($keyword_tokens as $keyword) {
  $keyword = mysqli_real_escape_string(trim($keyword));
  if (!empty($sql)) $sql .= " UNION "; 
  $sql .= "SELECT * FROM tbl_address WHERE address LIKE'%$keyword%'";
  // query and collect the result to $result
  // before inserting to $result, check if the id exists in $result.
  // if yes, skip.
}

ここでクエリを実行します。

于 2013-04-16T10:22:08.443 に答える