[英]MySQL & PHP : Multiple Keyword Search
I have a string containing comma separated keywords. 我有一个包含逗号分隔关键字的字符串。 For Example:
例如:
$keywords = 'keyword1, keyword2, keyword3';
My Table schema, named tbl_address
is like this ( simplified ) : 我的表模式,名为
tbl_address
,就像这样(简化):
id INT(11) PRIMARY KEY, AUTO INCREMENT
address VARCHAR(250) NOT NULL
Assume I have to use MySQLi
in PHP ( not PDO
). 假设我必须在PHP(而不是
PDO
)中使用MySQLi
。
Here is my current approach: 这是我目前的做法:
$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;
This approach works, but inefficient in performance. 这种方法有效,但性能效率低下。 If there are a lot of keywords, it will make a lot queries.
如果有很多关键字,它会产生很多查询。
My question is, is there a better way to achieve the same goal ? 我的问题是,有没有更好的方法来实现同一目标? ie what is the simplest way to return all records with the address containing the ANY of the keywords ?
即,使用包含任意关键字的地址返回所有记录的最简单方法是什么?
A simple REGEXP
might be what you're after. 一个简单的
REGEXP
可能就是你所追求的。 You'd have to check how efficient it is for yourself. 你必须检查它对你自己的效率。
SELECT * FROM tbl_address WHERE field REGEXP 'keyword1|keyword2|keyword3';
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 |
+---------+----------+
You only need an 'OR', nothing else... 你只需要一个'或',别的......
<?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;
edit: Just to be sure you also trim the keywords 编辑:只是为了确保你还修剪关键字
<?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;
Also, you should also pass the db resource link to the mysqli_real_escape_string()
function... 此外,您还应该将db资源链接传递给
mysqli_real_escape_string()
函数...
The best way is to use fulltext search. 最好的方法是使用全文搜索。
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
if you don't want to use fulltext you can use OR in your WHERE condition 如果您不想使用全文,则可以在WHERE条件中使用OR
SELECT * FROM tbl_address WHERE address LIKE '%$keyword%' OR adress LIKE '%$keyword2%'
Make single query 进行单一查询
$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;
Try WHERE IN clause: 尝试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).'")';
Successfully tested on MySQL 5.1. 在MySQL 5.1上成功测试。
Best way is just create search string WHERE clause and append it to query and run it once. 最好的方法是创建搜索字符串WHERE子句并将其附加到查询并运行一次。
$result = array();
$keyword_tokens = explode(',', $keywords);
$where = '';$i=0
foreach($keyword_tokens as $keyword) {
$where.= " address LIKE'%".mysqli_real_escape_string(trim($keyword))."%' OR ";
}
// trim last OR with substr_replace
substr_replace($where, "OR", -1, 1);
$sql = "SELECT * FROM tbl_address WHERE $where";
return $result;
Hi create a query with union and execute in the end of the loop 您好用union创建一个查询并在循环结束时执行
$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.
}
Execute the query here. 在这里执行查询。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.