【发布时间】:2010-06-24 19:58:40
【问题描述】:
现在我只是用一个简单的
WHERE name LIKE '%$ser%'
但我遇到了一个问题 - 假设搜索是测试 123,而“名称”是测试,它没有返回任何结果。知道有什么方法可以解决吗?我做错了吗?
【问题讨论】:
-
您能解释一下您正在尝试做什么以及为什么您希望搜索“testing 123”会在名称“testing”上给出肯定匹配吗?你什么时候不希望它匹配?
现在我只是用一个简单的
WHERE name LIKE '%$ser%'
但我遇到了一个问题 - 假设搜索是测试 123,而“名称”是测试,它没有返回任何结果。知道有什么方法可以解决吗?我做错了吗?
【问题讨论】:
如果您想搜索“测试”或“123”,请使用OR:
WHERE (name LIKE '%Testing%' OR name LIKE '%123%')
但是请注意,这将非常慢,因为无法使用索引,并且可能会返回一些您不想要的结果(例如“4123”)。根据您的需要,使用 full text search 或外部数据库索引产品(如 Lucene)可能是更好的选择。
【讨论】:
这就是 LIKE 的工作原理 - 它返回 完全 包含搜索字符串的行,并且,如果您使用“%”,则可以选择包含其他内容。
如果要查看字段是否包含在字符串中,可以这样:
SELECT * FROM `Table` WHERE "Testing 123" LIKE CONCAT("%",`name`,"%")
【讨论】:
正如 Scott 所提到的,您无法检查搜索是否包含列值,反之亦然。
所以如果$ser = "testing" 和表有一行name = testing 123 它将返回
对于您要执行的操作,您需要将搜索查询标记为术语,并对它们中的每一个执行 OR 搜索,或者最好还是查看 mysql full text search 以获得更好的方法
【讨论】:
变量$ser替换后,查询为:
WHERE name LIKE '%Testing 123%'
您应该构建以单词分隔的查询:
WHERE name LIKE '%$word[1]%$word[2]%'
【讨论】:
效率不高(如您的示例),但可以按您的意愿工作:
WHERE name LIKE '%$ser%' OR '$ser' LIKE CONCAT('%', name, '%')
【讨论】:
正如 Mark 和其他人所提到的,如果可能,全文搜索方法可能会更好。
但是,您可以在单词边界上拆分搜索字符串并使用 OR 逻辑 - 但首先检查整个字符串,然后提供扩大搜索范围的选项:
注意:输入消毒和准备未显示。
1。查询:
$sql_where = "WHERE name LIKE '%$ser%'";
2.如果返回零个结果,请询问用户是否愿意单独查询每个单词。
3. 如果用户请求“每个单词”搜索,则查询:
$sql_where = get_sql_where($ser);
(工作)示例代码如下:
$ser = 'Testing 123';
$msg = '';
function get_sql_where($ser){
global $msg;
$sql_where = '';
$sql_where_or = '';
$ser = preg_replace("/[[:blank:]]+/"," ", trim($ser)); //replace consecutive spaces with single space
$search_words = explode(" ", $ser);
if($search_words[0] == ''){
$msg = 'Search quested was blank.';
}else{
$msg = 'Search results for any of the following words:' . implode(', ', $search_words);
$sql_where = "WHERE name LIKE '%$ser%'";
foreach($search_words as $word){
$sql_where_or .= " OR name LIKE '%$word%'";
}
}
return $sql_where . $sql_where_or;
}
$sql_where = get_sql_where($ser);
//Run query using $sql_where string
【讨论】: