2016-06-07 63 views
1

我有一個簡單的請求:按用戶名搜索。 不過,想象我會對數據庫這樣的數據:Mysql - 按標記字符串搜索

1 - John Amazing Doe 
2 - John Stupid Doe 
3 - John Anthony 

當我用「李四」搜索,有沒有一種簡單的方法由具有「約翰」或「母鹿」的結果進行搜索嗎?更好的是,如果我們可以根據誰有更多的比賽來排名?

感謝

+4

您可以使用全文索引做到這一點。這是一個開始的地方:http://dev.mysql.com/doc/refman/5.7/en/fulltext-natural-language.html。 –

回答

1

數據準備構建查詢

這東西會發送到MySQL之前,最好的處理方式稍有編程之前。

名字依次放入一個列表,空間突破:

  • "John Doe" --> "John|Doe"
  • SELECT用戶名FROM用戶其中username RLIKE '約翰|李四'

要小心這裏的SQL注入。

PHP示例

$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>'; 
} 
1

全文索引和MATCH()是您最佳的選擇。這就是說,這裏是另一種方式:

您可以搜索具有「約翰」或「李四」使用LIKE名稱:

SELECT user_name 
FROM users 
WHERE user_name LIKE 'John%' 
OR  user_name LIKE '%Doe' 

使用開頭和結尾%只有名稱不會總是以' John'或以'Doe'結尾,否則使用一個。雙%不會利用你有任何的索引上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它不會。只要有可能就添加全文索引的另一個原因。