首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 多表字段模糊匹配:CONCAT 構建 LIKE 模式的正確姿勢

     編輯:MySQL 資料庫相關知識

在多表關聯查詢中,常需根據一張表的字段值,去另一張表做模糊匹配(如:標簽表匹配文章標題、分類名匹配商品描述)。MySQL 中不能直接用 + 或 || 拼接字符串,必須使用 CONCAT() 函數構建 LIKE 模式。本文通過反面教材與正確示例,釐清核心用法。

錯誤示範

-- 錯誤:MySQL 中 + 是算術加法,非字符串拼接;|| 在默認 SQL 模式下是邏輯 OR
SELECT info.id, info.name 
FROM tag, info 
WHERE info.name LIKE '%' + tag.name + '%';  -- 結果全為 0 或報錯

-- 錯誤:Oracle/PostgreSQL 風格,MySQL 默認不支持
SELECT info.id, info.name 
FROM tag, info 
WHERE info.name LIKE '%' || tag.name || '%';

正確寫法:CONCAT() 構建模式

-- 標準寫法:CONCAT('%', 列名, '%')
SELECT info.id, info.name 
FROM tag, info 
WHERE info.name LIKE CONCAT('%', tag.name, '%');

CONCAT(str1, str2, ...) 返回拼接後的字符串,任一參數為 NULL 則結果為 NULL。若需容忍 NULL,可用 CONCAT_WS('', '%', tag.name, '%') 或 IFNULL(tag.name, '')。

實戰場景:EmpireCMS 次級表關聯

源碼片段展示了 CMS 系統中主表 table 與關聯表 table1 的查詢,table1.sid 存儲管道分隔的 ID 串(|1|2|3|),需反向匹配:

$sql = $empire->query("
    SELECT table.title, lianxi, table.dizhi, table.id 
    FROM table, table1 
    WHERE table1.sid LIKE CONCAT('%|', table.id, '|%') 
      AND table1.id = " . $navinfor[id]
);

CONCAT('%|', table.id, '|%') 生成 %|123|% 模式,精確匹配邊界,避免誤匹配 1234、1123 等。

效能警示與優化建議

問題影響優化方案
LIKE '%xxx%' 導掛首字符通配無法利用 B-Tree 索引,全表掃描1. 全文索引 FULLTEXT + MATCH() AGAINST()
2. 外部搜索引擎
3. 將標簽拆分為關聯表(多對多),走等值 JOIN
跨表模糊匹配 + 大數據量笛卡爾積 + 全掃描,極慢業務層面拆解:寫入時預計算關聯,查詢時走精確 JOIN

最佳實踐總結

  1. 拼接模式必用 CONCAT(),切勿用 + 或 ||。
  2. 邊界分隔符:存儲列表型字符串時,首尾加分隔符(|id|),查詢用 CONCAT('%|', id, '|%') 精確匹配。
  3. 避免業務邏輯依賴模糊匹配:設計階段改用關聯表(tag_map),將 O(N*M) 降為 O(log N)。
  4. 必須模糊時:小表驅動大表、加 LIMIT、考慮 FULLTEXT 或 Elasticsearch。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved