2013-05-15 73 views
0

我正在開發一個網站,該網站允許用戶列出待售的船隻和遊艇。有一個mysql數據庫有一個表「遊艇」,其他領域有「製造」和「模型」。MySql搜索兩個組合字段的查詢

當有人來到該網站尋找出售船隻時,有一個搜索表單,其中一個選項是將製造商和/或模型輸入到文本字段中。有關在搜索結果頁上的條款是以下

WHERE (make LIKE '%$yacht_make%' OR model LIKE '%$yacht_make%') 

這是工作,如果有人進入要麼廠名模型但如果他們進入兩者。

例如,如果有人輸入「Jeanneau」,製造商會發現該製造的船,或者如果他們進入了「Sun Odyssey」模型,它會找到該模型的船,但是如果他們進入「 Jeanneau Sun奧德賽「它變得空虛。

有沒有一種方法來編寫一個查詢,其中所有三種方式進入上述搜索條件會找到船?

這裏是網站http://yachtsoffered.com/

感謝,

羅布·芬威克

編輯:

查詢是建立與PHP腳本這裏是腳本

if(!empty($yacht_id)) { 
    $where = " WHERE yacht_id = $yacht_id "; 
} else { 
    $where = " WHERE (make LIKE '%$yacht_make%' OR model LIKE '%$yacht_make%') "; 
    if(!empty($year_from) && !empty($year_to)){ 
     $where .= "AND (year BETWEEN $year_from AND $year_to) "; 
    } 
    if(!empty($length_from) && !empty($length_to)){ 
     $where .= "AND (length_ft BETWEEN $length_from AND $length_to) "; 
    } 
    if(!empty($price_from) && !empty($price_to)){ 
     $where .= "AND (price BETWEEN $price_from AND $price_to) "; 
    } 
    if ($sail_power != 2){ 
     $where .= "AND (sail_power = $sail_power) "; 
    } 
    if (count($material_arr) > 0){ 
     $material = 'AND ('; 
     foreach ($material_arr as $value) { 
      $material .= ' material LIKE \'%' . $value . '%\' OR'; 
     } 
     $material = substr_replace ($material , ') ' , -2); 
     $where .= $material; 
    } 
    if (count($engine_arr) > 0){ 
     $engine = 'AND ('; 
     foreach ($engine_arr as $value) { 
      $engine .= ' engine LIKE \'%' . $value . '%\' OR'; 
     } 
     $engine = substr_replace ($engine , ') ' , -2); 
     $where .= $engine; 
    } 
    if (count($type_arr) > 0){ 
     $type = 'AND ('; 
     foreach ($type_arr as $value) { 
      $type .= ' type LIKE \'' . $value . '\' OR'; 
     } 
     $type = substr_replace ($type , ') ' , -2); 
     $where .= $type; 
    } 
    if (count($region_arr) > 0){ 
     $region = 'AND ('; 
     foreach ($region_arr as $value) { 
      $region .= ' region LIKE \'' . $value . '\' OR'; 
     } 
     $region = substr_replace ($region , ') ' , -2); 
     $where .= $region; 
    }  
     $where .= 'AND (active = 1) ORDER BY yacht_id DESC'; 
} 

$sql = "SELECT * FROM $tbl_name $where LIMIT $start, $limit"; 
$result = mysql_query($sql); 
+0

你可以發佈你的整個查詢? –

+0

當兩個都進入你的搜索一個領域與製造和模型,所以它失敗了,你需要明確分開2,使用2個輸入,或拆分文本用戶輸入 – 2013-05-15 20:04:17

+0

謝謝達貢,是的,我明白爲什麼它不是工作中,我想到了對兩個輸入字段進行篩選,但我想知道是否還有其他選項,但是吐出它們的問題是無法分辨哪些詞是模型的成分,我想我可以搜索每個詞單詞,但會帶來太多的結果。 –

回答

1

有很多方法可以做到這一點,在我看來,最簡單的一種是:

$search = preg_replace('/\s+/','|', $yacht_make); 
$sql = "select * from yacht where concat_ws(' ',make,model) rlike '$search'"; 

該命令替換|所有空白,即在正則表達式作爲OR所有可搜索字段串聯的動力類查詢。它的速度在重型交通網站可能有問題,但相當緊湊,並且易於添加更多的領域。

+0

這麼容易做到。 RLIKE在mysql問題的答案中遠未得到充分利用。也像concat_ws一樣。人們的參考文獻是CONCAT_WS(http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat-ws)和RLIKE(http://dev.mysql.com/doc/refman /5.0/en/regexp.html#operator_regexp) – JClaspill

+0

我得到這個錯誤的preg_replace線解析錯誤:語法錯誤,意外的'/',期待')'在C:\ xampp \ htdocs \ yachtsoffered \ results.php on第70行 –

+0

對不起,當然應該引用regexp字符串... –

0

你的問題是在你的查詢中尋找確切的子字符串「Jeanneau Sun Odyssey」,這既不是品牌也不是模型。

最簡單的解決方案是用來分隔品牌和型號的輸入框。但是,如果你真的需要使用一個輸入框,你最好的選擇將是分裂的空間,並添加子句對每個單獨的字,所以您的查詢最終會看起來像

WHERE make like '%sun%' OR model like '%sun%' 
OR make like '%odyssey%' OR model like '%odyssey%' 
OR make like '%Jeanneau%' OR model like '%Jeanneau%' 
-1

檢查你的網站後它似乎只是從一個文本字段進行輸入並在每個字段中搜索該字符串。

因此,您可以使用全文搜索(linkie),也可以用空格分隔字符串,並在飛行中生成WHERE原因。下面是一個粗略的例子:

$searchterms = explode (' ', $input); 

$sql .= "... WHERE"; /* obviously need the rest of your query */ 


foreach ($searchterms as $term) { 
    if ((substr ($string, -5) != 'WHERE') && 
     (substr ($string, -3) == ' ||') { $sql .= " ||"; } 
    $sql .= " make LIKE '%$term%' || model LIKE '%$term%'"; 
} 
+0

只是注意到一個錯誤 - 將解決! –

+0

這裏需要一些[適當的SQL轉義](http://bobby-tables.com/php)。 – tadman

0

您還可以使用:

WHERE make LIKE '%$yacht_make%' 
    OR model LIKE '%$yacht_make%' 
    OR '$yacht_make' LIKE CONCAT('%', make, '%', model, '%') 
    OR '$yacht_make' LIKE CONCAT('%', model, '%', make, '%') 

這不會是非常有效的,但仍不能趕上所有的可能性,例如如果用戶提供製造商和型號名稱的一部分,如'Jeanneau Odyssey'或錯誤順序:Sun Jeanneau Odyssey

+0

我已經在這個位置的次數,並不知道你可以做到這一點!我現在要去改變一些搜索,所以我把它放在我的代碼中 - 謝謝 – 2013-05-15 20:30:34

+0

@Lagon'%searchstring'' @Dagon查詢效率不高。 –

+0

LIKE中的反轉參數是很好的特性,但在這裏它會使任何事情都很難找到 - 你必須提供精確的製作和模型,可選地分開,前綴和後面跟任何不相關的東西,但沒有結果用於只有make或只有模型的查詢或與每一個的一部分。它會發現''123 Jeanneau 123 Sea Odyssey 213「',但沒有''Jeanneau Odyssey」' –

0

謝謝大家我結束了使用上述

開發無效居民的解決方案我修改我的代碼如下,

獲得的價值和逃避這裏是代碼,

if (isset($_GET['yacht_make'])) { 
    $yacht_make = cleanString($_GET['yacht_make']); 
    $yacht_make = preg_replace('/\s+/','|', $yacht_make); 
} else { 
    $yacht_make = NULL; 
} 

並且我修改了我上面發佈的php查詢構建代碼的前幾行以讀取,

if(!empty($yacht_id)) { 
    $where = " WHERE yacht_id = $yacht_id "; 
} else { 

    $where = " WHERE (yacht_id LIKE '%')"; 

    if(!empty($yacht_make)){ 
     $where .= "AND (CONCAT_WS(' ',make,model) RLIKE '$yacht_make') "; 
    } 

雖然它帶來了比我想要的「Jeanneau Sun Odyssey」更多的效果,但它帶來了「Bayliner Sunbridge」,我假設它是匹配「Sun」。

但是,這是一個很大的改進,從我了。

感謝所有

羅布·芬威克