2013-01-20 72 views
2

我正在尋找模型編號的搜索功能,我試圖讓MySQL向我展示類似於我所要求的結果,但LIKE%$ var%並沒有這樣做。在MySQL中,如何返回包含「類似」數據的行到我要求的?

例(我們稱之爲表, 「tbl_models」):

id   model 
+-------+--------------------+ 
| 1 | DV6233SE  | 
| 2 | Studio 1440  | 
| 3 | C762NR   | 
+-------+--------------------+ 

當使用搜索框搜索我目前使用:

SELECT id, model FROM tbl_models WHERE model LIKE %$var% ORDER BY id DESC 

如果我搜索 「C7」它會返回「C762NR」這很好,但說我要搜索「C760」或「C700」或「C726NR」的錯字?在MySQL(或PHP,JS,jQuery)中有沒有辦法可以擴展返回結果的限制以包含不同的變體或關閉匹配?

我不想找人爲我寫信,只要按正確的方向就會很有幫助!

+1

查看http://stackoverflow.com/questions/13114398/how-can-i-match-two-strings-even-if-they-are-1-character-different/13114599 – Aea

+0

檢查[this](http ://stackoverflow.com/a/3339034/913097)並在這裏進行搜索。有很多。 – inhan

+0

根據代碼欄中有多少個字符,您可以使用lik'%C7 ____%' – Taicho

回答

2

如果我要爲你的問題申請邏輯,我會這樣。

尋找近似匹配 -

我將採用最初由用戶鍵入的輸入參數。例如'ABCDEF' 然後,我將通過用'_'替換輸入參數中的每個字符來創建多個參數。

I.e. 'ABCDEF'將爲我生成以下輸入參數。

'_BCDEF', 'A_CDEF', 'AB_DEF', 'ABC_EF', 'ABCD_F', 'ABCDE_'

然後我會把輸入參數,SQL查詢,使用或操作來尋找數據。

上面的方法會讓我的單詞相差1個字符。

我可以通過用UNDERSCORE替換2個字符,然後3個字符然後4等等來擴展這個。

上面有多少個字符需要替換,取決於字符串的長度。

+0

謝謝。這似乎是我最好的選擇。當用戶執行搜索時,我將不得不創建一個可能的匹配數組。我正在考慮使用jQuery/PHP實現自動完成功能,我會試一試。謝謝。 –

+0

歡迎!請在執行代碼後發佈代碼。這對所有人都有用。 –

+0

將代碼作爲新答案發布,而不是編輯OP。是建議還是應該將其移至OP? –

1

看看這個功能...這就是你要找的,我想:http://php.net/manual/en/function.levenshtein.php。 這個功能可能是另一種選擇,但我建議你不要使用它,因爲結果可能有點不可預知:http://www.php.net/manual/en/function.similar-text.php

要實現您正在尋找的最佳方式是使用natural languages full-text searches

+0

謝謝,但大多數這些內置功能似乎都需要真實的文字,而我所搜索的文本是型號(例如AB-1234)。 –

0

您可以使用上述的PHP函數,或者SOUNDEX可以幫助您。看看this

+0

從我讀過的SOUNDEX中可以找到使用語音的方法,但是在模型數字的情況下,它通常不是單詞,而是字母數字混合。 –

1

根據SaurabhV提供的答案(再次感謝!),我能夠創建一個函數,它接受一個字符串並按順序用下劃線替換每個字母。我希望這可以幫助其他人在路上!

function get_combination($string) { 
    // Pa = Pass, Pos = Character Position, Len = String Length 

    $str_arr = array($string); 
    $Len = strlen($string); 
    for ($Pa=0;$Pa<$Len;$Pa++) { 
     for($Pos=1;($Pos+$Pa)<=$Len;$Pos++) { 
      if($Pos+$Pa == $Len && $Pos<$Pa) { 
       array_push($str_arr, substr_replace($string, str_repeat('_', $Pos), $Pa, 1)); 
      } else if($Pos+$Pa == $Len && $Pos>$Pa) { 
       // End of String 
      } else if($Pos == $Len || ($Len > 2 && $Pos == ($Len-1))) { 
       // Do nothing - $Pos is too high 
      } else if($Pos > $Len/2 && $Len > 6) { 
       array_push($str_arr, substr_replace($string, str_repeat('_', $Pos-4), $Pa, $Pos-4)); 
      } else { 
       array_push($str_arr, substr_replace($string, str_repeat('_', $Pos), $Pa, $Pos)); 
      } 
     } 
    } 
    return $str_arr; 
} 

例子:

$string = get_combination('dv6000'); 

返回:

Array ([0] => dv6000 [1] => _v6000 [2] => __6000 [3] => ___000 [4] => ____00 [5] => d_6000 [6] => d__000 [7] => d___00 [8] => d____0 [9] => dv_000 [10] => dv__00 [11] => dv___0 [12] => dv6_00 [13] => dv6__0 [14] => dv6___ [15] => dv60_0 [16] => dv60__0 [17] => dv600_) 

現在使用的MySQLi和foreach循環我能夠對陣列在數據庫中搜索相似的結果是什麼問。正如你在例子中看到的那樣,「dv6000」是被問到的字符串,但是在tbl_models(見OP)中沒有dv6000。一旦數據庫命中指數14(dv6___),它會找到正確的條目:

SELECT model_number FROM tbl_models WHERE model_number LIKE %string[14]% 

它的混亂,可能不是很有效,但它的作品。如果任何人都可以詳細說明,或者可能幫助我清理這些代碼,使其更簡化,如果可能的話,我會很感激!

相關問題