You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SQL拆分逗号分隔字符串为多列,忽略双引号内的逗号

如何用SQL拆分带引号的CSV字符串(忽略引号内的逗号)

针对你给出的CSV字符串Steve,Mark,"1,2",Final,需要拆分时跳过双引号内部的逗号,以下是主流SQL数据库的实现方案:

MySQL 解决方案

方法1:正则表达式提取(MySQL 8.0+)

利用MySQL 8.0及以上支持的正则函数,直接匹配符合规则的列内容:

SELECT
  REGEXP_SUBSTR(csv_str, '(?<=^|,)([^",]+|"[^"]*")(?=,|$)', 1, 1) AS col1,
  REGEXP_SUBSTR(csv_str, '(?<=^|,)([^",]+|"[^"]*")(?=,|$)', 1, 2) AS col2,
  REGEXP_SUBSTR(csv_str, '(?<=^|,)([^",]+|"[^"]*")(?=,|$)', 1, 3) AS col3,
  REGEXP_SUBSTR(csv_str, '(?<=^|,)([^",]+|"[^"]*")(?=,|$)', 1, 4) AS col4
FROM (
  SELECT 'Steve,Mark,"1,2",Final' AS csv_str
) t;

正则规则说明:匹配两种合法列内容——要么是不含逗号和引号的普通字符串,要么是被双引号包裹、内部可包含任意字符(除引号)的内容,同时确保匹配的内容是完整的列(前后为字符串开头/结尾或逗号)。

方法2:自定义函数(兼容低版本MySQL)

如果你的MySQL版本低于8.0,没有正则函数,可以编写自定义拆分函数:

DELIMITER //
CREATE FUNCTION split_quoted_csv(str TEXT, pos INT) 
RETURNS TEXT
DETERMINISTIC
BEGIN
  DECLARE current_pos INT DEFAULT 1;
  DECLARE current_col INT DEFAULT 1;
  DECLARE in_quote BOOLEAN DEFAULT FALSE;
  DECLARE result TEXT DEFAULT '';
  
  WHILE current_pos <= LENGTH(str) AND current_col <= pos DO
    SET result = '';
    WHILE current_pos <= LENGTH(str) DO
      IF SUBSTRING(str, current_pos, 1) = '"' THEN
        SET in_quote = NOT in_quote;
        SET result = CONCAT(result, SUBSTRING(str, current_pos, 1));
        SET current_pos = current_pos + 1;
      ELSEIF SUBSTRING(str, current_pos, 1) = ',' AND NOT in_quote THEN
        SET current_pos = current_pos + 1;
        SET current_col = current_col + 1;
        LEAVE;
      ELSE
        SET result = CONCAT(result, SUBSTRING(str, current_pos, 1));
        SET current_pos = current_pos + 1;
      END IF;
    END WHILE;
    IF current_col = pos THEN
      RETURN result;
    END IF;
  END WHILE;
  RETURN NULL;
END //
DELIMITER ;

-- 调用函数拆分
SELECT
  split_quoted_csv('Steve,Mark,"1,2",Final', 1) AS col1,
  split_quoted_csv('Steve,Mark,"1,2",Final', 2) AS col2,
  split_quoted_csv('Steve,Mark,"1,2",Final', 3) AS col3,
  split_quoted_csv('Steve,Mark,"1,2",Final', 4) AS col4;

PostgreSQL 解决方案

PostgreSQL 14+内置了csv_parse函数,可直接处理带引号的CSV:

SELECT
  (csv_parse(csv_str)).col1,
  (csv_parse(csv_str)).col2,
  (csv_parse(csv_str)).col3,
  (csv_parse(csv_str)).col4
FROM (
  SELECT 'Steve,Mark,"1,2",Final'::text AS csv_str
) t;

如果版本低于14,可使用正则拆分函数:

SELECT
  arr[1] AS col1,
  arr[2] AS col2,
  arr[3] AS col3,
  arr[4] AS col4
FROM (
  SELECT regexp_split_to_array('Steve,Mark,"1,2",Final', '(?<=^|,)([^",]+|"[^"]*")(?=,|$)') AS arr
) t
WHERE arr[1] IS NOT NULL;

SQL Server 解决方案

通过将CSV转换为JSON数组,利用JSON_VALUE提取列,实现简单高效:

SELECT
  JSON_VALUE(json_str, '$[0]') AS col1,
  JSON_VALUE(json_str, '$[1]') AS col2,
  JSON_VALUE(json_str, '$[2]') AS col3,
  JSON_VALUE(json_str, '$[3]') AS col4
FROM (
  SELECT '["' + REPLACE(REPLACE('Steve,Mark,"1,2",Final', '"', '""'), ',', '","') + '"]' AS json_str
) t;

原理:先将原字符串中的双引号转义为JSON格式的双引号,再用","替换分隔逗号,最后包裹成JSON数组,即可通过JSON函数提取各列。


内容的提问来源于stack exchange,提问作者Sreepathi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:27:38