首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 字符串拼接函數 CONCAT 與 CONCAT_WS 完全指南

     編輯:MySQL 綜合教學

核心函數對比

函數語法行為NULL 處理典型場景
CONCATCONCAT(str1, str2, ...)直接拼接所有參數任一參數為 NULL → 結果為 NULL簡單拼接、構建動態 SQL
CONCAT_WSCONCAT_WS(sep, str1, str2, ...)用分隔符拼接,跳過 NULL自動忽略 NULL 參數路徑拼接、CSV 生成、標籤聚合

CONCAT 詳細行為

SELECT CONCAT('My', 'S', 'QL');        -- 'MySQL'
SELECT CONCAT('My', NULL, 'QL');       -- NULL
SELECT CONCAT(14.3);                   -- '14.3' (數字隱式轉字符串)
SELECT CONCAT(CAST(100 AS CHAR), 'abc'); -- '100abc' 顯式轉型避免二進制字符串

二進制字符串陷阱:若任一參數為二進制字符串(如 BLOB、BIT、未轉型的數字),結果為二進制字符串,可能導致字符集比較異常。建議顯式 CAST(... AS CHAR)。

CONCAT_WS 實戰優勢

-- 路徑拼接(自動處理 NULL、不產生雙分隔符)
UPDATE users SET home_dir = CONCAT_WS('/', '/data/disk1', part, user) WHERE id=1;
-- 結果:/data/disk1/part1/user1  (若 part 為 NULL → /data/disk1/user1)

-- 標籤聚合(配合 GROUP_CONCAT)
SELECT user_id, CONCAT_WS(',', tag1, tag2, tag3) AS tags FROM user_tags;

-- 動態構建 WHERE IN 列表
SET @ids = CONCAT_WS(',', 1, 2, NULL, 4);  -- '1,2,4'
PREPARE stmt FROM CONCAT('SELECT * FROM t WHERE id IN (', @ids, ')');

常見陷阱與避坑

1. NULL 導致全 NULL

CONCAT('a', NULL, 'b') 返回 NULL。解決:CONCAT('a', IFNULL(col, ''), 'b') 或改用 CONCAT_WS('', 'a', col, 'b')(空分隔符)。

2. 字符集隱式轉換報錯

拼接不同字符集列(如 utf8mb4 + latin1)會報 Illegal mix of collations。解決:CONCAT(CONVERT(col1 USING utf8mb4), CONVERT(col2 USING utf8mb4)) 或統一表字符集。

3. 超過 max_allowed_packet 截斷

拼接超長字符串(> 4MB 默認)會靜默截斷並產生警告。檢查 SHOW WARNINGS,調大 max_allowed_packet 或分塊處理。

4. 數字隱式轉換產生科學計數法

CONCAT(1e10) → '10000000000.0' 而非 '10000000000'。解決:CAST(num AS CHAR) 或 FORMAT(num, 0)。

進階用法:構建動態 SQL 與 JSON

-- 安全構建 IN 列表(防注入)
SET @safe_ids = CONCAT_WS(',', 
    (SELECT QUOTE(id) FROM tmp_ids WHERE batch=1)
);
PREPARE s FROM CONCAT('SELECT * FROM orders WHERE id IN (', @safe_ids, ')');

-- 模擬 JSON_OBJECT(5.7- 無原生函數時)
SELECT CONCAT('{"name":"', REPLACE(name, '"', '\\"'), '","age":', age, '}') AS json_str FROM users;

性能提示

  • CONCAT/CONCAT_WS 都是 CPU 密集型,避免在大結果集(>10萬行)的 SELECT 列表中濫用。
  • 可在應用層拼接,或用生成列(Generated Column)持久化:full_path VARCHAR(500) GENERATED ALWAYS AS (CONCAT_WS('/', base, sub)) STORED。
  • 索引無法直接作用於函數結果,若需搜索拼接值,建議生成列 + 索引。

總結

CONCAT 適合無 NULL、無分隔符的簡單拼接;CONCAT_WS 是處理可選字段、路徑、列表拼接的「瑞士軍刀」,自動跳過 NULL、自帶分隔符。牢記 NULL 語義差異、字符集一致性、長度限制,即可在 SQL 中靈活高效地操作字符串。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved