我有一个简单的请求:按用户名搜索。 不过,想象一下我在数据库上有这些数据:
1 - John Amazing Doe
2 - John Stupid Doe
3 - John Anthony
当我通过" John Doe"进行搜索时,是否有一种简单的方法来搜索具有" john"或" doe"?更好的是,如果我们可以按谁拥有更多匹配进行排名?
由于
答案 0 :(得分:1)
全文索引和MATCH()
是您的最佳选择。也就是说,这是另一种方式:
您可以搜索包含' John'或者' Doe'使用LIKE
:
SELECT user_name
FROM users
WHERE user_name LIKE 'John%'
OR user_name LIKE '%Doe'
仅当姓名不会始终以' John'开头时,才使用前导和尾随%
。或者以“Doe”结尾,否则使用一个。 Double %
不会使用user_name
然后,您可以使用UNION
和排序列对这些进行排名:
SELECT user_name, 1 as Sort_Col
FROM users
WHERE user_name LIKE 'John%'
AND user_name LIKE '%Doe'
UNION
SELECT user_name, 2 as Sort_Col
FROM users
WHERE (user_name LIKE 'John%'
OR user_name LIKE '%Doe')
AND user_name NOT IN (
SELECT user_name
FROM users
WHERE user_name LIKE 'John%'
AND user_name LIKE '%Doe')
ORDER BY Sort_Col ASC
您必须在第二个查询中使用烦人的NOT IN
,以确保您不会返回同时包含“John'和' Doe'。通常情况下UNION
就足够了,但由于我们添加了Sort_Col
,因此不会。只是在可能的情况下添加全文索引的另一个原因。
答案 1 :(得分:1)
这是在发送到MySQL之前以编程方式处理的最佳方法。
将名称转换为列表,中断空格:
"John Doe" --> "John|Doe"
这里注意sql注入。
$db = new PDO([conn info]);
$searchArg = 'John Doe';
$nameRegex = str_replace(' ','|', strtolower($searchArg));
$userSearch = $db->prepare('SELECT username FROM users WHERE LOWER(username) REGEXP :nameRegex');
$userSearch->bindValue(':nameRegex', $nameRegex, PDO::PARAM::STR);
$userSearch->execute();
foreach ( $userSearch->fetchAll(PDO::FETCH_ASSOC) as $user ) {
echo $user['username'] . '\n<br>';
}