Ответ 1
Простым REGEXP
может быть то, что вам нужно. Вам нужно будет проверить, насколько он эффективен для вас.
SELECT * FROM tbl_address WHERE field REGEXP 'keyword1|keyword2|keyword3';
У меня есть строка с запятыми. Например:
$keywords = 'keyword1, keyword2, keyword3';
Схема My Table, названная tbl_address
, подобна этой (упрощенной):
id INT(11) PRIMARY KEY, AUTO INCREMENT
address VARCHAR(250) NOT NULL
Предположим, что я должен использовать MySQLi
в PHP (не 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;
Этот подход работает, но неэффективен по производительности. Если есть много ключевых слов, это вызовет много запросов.
Мой вопрос: есть ли лучший способ достичь той же цели? то есть самый простой способ вернуть все записи с адресом, содержащим ЛЮБОЕ из ключевых слов?
Простым REGEXP
может быть то, что вам нужно. Вам нужно будет проверить, насколько он эффективен для вас.
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 |
+---------+----------+
Вам нужен только "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;
edit: просто убедитесь, что вы также обрезаете ключевые слова
<?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()
...
Сделать одиночный запрос
$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;
Попробуйте предложение 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.
Лучший способ - использовать полнотекстовый поиск.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
Если вы не хотите использовать полнотекстовый текст, вы можете использовать OR в состоянии WHERE
SELECT * FROM tbl_address WHERE address LIKE '%$keyword%' OR adress LIKE '%$keyword2%'
Лучший способ - просто создать предложение WHERE 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;
Привет, создайте запрос с объединением и выполните в конце цикла
$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.
}
Выполните запрос здесь.