2013-04-16 265 views
10

我有一個包含逗號分隔關鍵字的字符串。例如:MySQL和PHP:多關鍵字搜索

$keywords = 'keyword1, keyword2, keyword3'; 

我的表架構,命名爲tbl_address是這樣(簡化):

id  INT(11)  PRIMARY KEY, AUTO INCREMENT 
address VARCHAR(250) NOT NULL 

假設我在PHP中使用MySQLi(不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; 

這種方法有效,但在性能上效率低下。如果有很多關鍵字,它會做很多查詢。

我的問題是,是否有更好的方法來實現相同的目標?即用包含任何關鍵字的地址返回所有記錄的最簡單方法是什麼?

+0

這可以幫助你:http:// stackoverflow。com/a/9736386/1983854 – fedorqui

+0

結合「LIKE」和「IN」:http://stackoverflow.com/questions/1865353/combining-like-and-in-for-sql-server – Chris

+2

@Shivian認真,爲什麼didn'你用我的REGEXP單線? – Jimbo

回答

17

一個簡單的REGEXP可能是你所追求的。你必須檢查自己的效率。

SELECT * FROM tbl_address WHERE field REGEXP 'keyword1|keyword2|keyword3';

+1

+1,這正是我所尋找的,我也學到了一個新的'MySQL'字符串函數! –

+1

優秀的答案,這幫助我解決了一週的研究,並幫助我跳過了我的問題的30%:) – Birdy

5
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  | 
+---------+----------+ 
+0

只是一個警告與這種方法。不能使用LIKE語法,並且不會修剪關鍵字... – arraintxo

0

剛剛創建的搜索字符串的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; 
0

嗨創建工會查詢,並在循環

$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. 
} 

年底執行此執行查詢。

3

你只需要一個 '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; 

編輯:只是要確保你也修剪關鍵字

<?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()函數...

+0

儘管您錯過了「$ sql」的尾部單引號。 – Raptor

+1

你說得對。 Allready added too :) – arraintxo

+0

這不起作用;它說我有SQL錯誤; – Eenvincible

1

進行單個查詢

$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; 
+1

在循環中,這不是'$ other。=「'而不是'$ other =」'嗎?否則,你將取消每個循環中的'或'子句。 – TheCarver

1

嘗試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測試成功。