
最近我們一位客戶在網站上查詢零件資料時,遇到一個奇怪的問題。
他們輸入的關鍵字類似:
Vaaon AA666-888 WEB %。
照理說,資料庫裡明明就有這筆零件編號,
但當我在 MySQL 裡下指令:
SELECT * FROM parts WHERE part_number LIKE '%Vaaon AA666-888 WEB %';
卻完全查不到任何結果。
一開始我以為是空白或編碼問題,
結果追查下來才發現
🕵️♂️ 兇手竟然是那兩個不起眼的符號: – 和 %。
它們在 LIKE 查詢中,其實不是普通字元,
而是被 MySQL 當成「特殊匹配符號」來處理。
% 與 _ 不是普通字元,而是「萬用字元」
在 MySQL 的 LIKE 條件查詢中,有兩個最常見的萬用符號:
| 符號 | 意義 | 範例 | 結果說明 |
|---|---|---|---|
| % | 代表「任意長度字元(0 個或多個)」 | LIKE '%ABC%' |
匹配包含「ABC」的所有字串 |
| _ | 代表「任意一個字元」 | LIKE 'A_C' |
匹配「AAC」、「ABC」、「ACC」等三個字元的字串 |
這兩個符號看似方便,但在搜尋時會造成誤判。
如果你的查詢字串裡剛好有 % 或 _,
MySQL 就會誤以為那是要當「萬用字元」使用,而不是你要查的實際內容。
那「-」又是怎麼回事?
💡 雖然 -(連字符號)在一般
LIKE 查詢中不是萬用符號,
但一旦搭配 [ ] 使用,例如:
LIKE '[a-z]',
它就會變成「範圍運算符」,表示匹配 a 到 z 之間的任意字元。
這也代表,只要你的字串中剛好含有 -,
又被包在某種不當的查詢邏輯中,
MySQL 可能就會誤判,導致結果不精準或完全查不到資料。
正確解法 — 用拆字匹配讓查詢更精準
知道原因後,我實際在專案中採用的方式,
是將使用者輸入的關鍵字先拆開,再逐一匹配。
這樣即使輸入中出現 %、- 或多個空白,也不會造成查詢錯誤,
同時能保留模糊搜尋的彈性。
實際程式範例(Laravel 寫法)
$keywords = preg_split(‘/\s+/’, $data[‘description’]);
$query = Model::query();
foreach ($keywords as $keyword) {
$keyword = trim($keyword);
if (!empty($keyword)) {
$query->where(‘description’, ‘like’, “%{$keyword}%”);
}
}
$results = $query->get();
這樣的查詢邏輯有三個好處:
- 避免誤判特殊字元:即使輸入中有
%、-、_等符號,MySQL 仍會當作普通字元處理。 - 可搜尋多組關鍵字:使用者輸入「Vaaon AA666-888 WEB %」時,系統會分別比對「Vaaon」、「AA666-888」、「WEB」、「%」,讓搜尋更寬鬆、容錯性更高。
- 方便擴充條件:若未來要支援多欄位查詢(例如
part_number、description、model),只要在foreach內新增orWhere()即可延伸。
原本不是我的專案,卻讓我意外發現新天地

這個專案原本並不是我負責開發的,當初只是臨時協助客戶處理搜尋異常的問題。
一開始我也一頭霧水——系統本身沒有報錯,資料也在,但輸入關鍵字 Vaaon AA666-888 WEB % 卻完全查不到。
直到我深入看程式邏輯、實際測試 LIKE 查詢,才發現這類符號在 MySQL 裡竟然會被誤判成「特殊匹配字元」。也因為這次的經驗,我才真正理解到:
搜尋邏輯不只是技術問題,而是一種對使用情境的理解。最後我改用「關鍵字拆分匹配法」,
讓系統能自動判斷並逐一搜尋多段內容,不只解決了客戶的需求,也讓我學到更通用、更彈性的查詢思維。
這段過程雖然只是小小的除錯任務,但卻讓我重新定義「模糊搜尋」的真正意義
不是模糊查資料,而是讓搜尋更懂人。






