資料庫設計中,有時為了簡化關聯,會在單一欄位(如 cateIds VARCHAR(80))以逗號分隔儲存多個 ID(例:'1,2'、'2,3')。查詢時需找出包含某 ID 的記錄,直接用 INSTR 或 LIKE 易產生誤判。
-- 錯誤寫法
SELECT * FROM Category
WHERE (SELECT INSTR(cateIds, cateId) FROM OpenRecord WHERE opreId = 1);
INSTR 做單純子字串搜尋,查 ID=1 時,'1,2'、'10,11'、'11,12' 都會被匹配,導致資料錯誤。
-- 正確寫法
SELECT * FROM Category
WHERE (SELECT FIND_IN_SET(cateId, cateIds) FROM OpenRecord WHERE opreId = 1);
FIND_IN_SET(str, strlist) 專為「逗號分隔列表」設計,只匹配完整元素,cateId=1 不會匹配到 10 或 11。
若分隔符為 |、; 等,可先用 REPLACE 轉為逗號再套用 FIND_IN_SET:
SELECT * FROM Category
WHERE FIND_IN_SET(cateId, REPLACE(cateIds, '|', ',')) > 0;
雖然 FIND_IN_SET 解決了查詢問題,但長期來看,規範化設計(建立中介表) 才是處理多對多關聯的正統做法,能發揮索引優勢、保證資料完整性。