【问题标题】:MySQL - Split a field and insert result into columnsMySQL - 拆分字段并将结果插入列
【发布时间】:2014-12-04 15:14:26
【问题描述】:

我正在尝试拆分字段(在某个分隔符处,在下面的示例中使用“;”)并将拆分结果插入到表中。下表说明了我正在尝试做的事情。

注意:在第一行中,由分号 (;) 分隔的值永远不会超过 3 个,但可以少于 3 个。

mysql> SELECT * FROM new;
+-------+------+------+------+
| first | a    | b    | c    |
+-------+------+------+------+
| a;b;c | NULL | NULL | NULL |
| d;e;f | NULL | NULL | NULL |
| g;h   | NULL | NULL | NULL |
| i     | NULL | NULL | NULL |
+-------+------+------+------+

查询的结果应该是这样的

mysql> SELECT * FROM new;
+-------+------+------+------+
| first | a    | b    | c    |
+-------+------+------+------+
| a;b;c | a    | b    | c    |
| d;e;f | d    | e    | f    |
| g;h   | g    | h    | NULL |
| i     | i    | NULL | NULL |
+-------+------+------+------+

我一直在尝试使用的查询是(这个特定的将只检索第一个值)。

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(first, ';', 1), ';', -1) FROM new;

但是,当分隔字符的数量少于 3 个时,此方法不会提供任何帮助,因为它会返回遇到的第一个字符,而不是 NULL 或空字符串 ("")。

任何人都知道如何解决这个问题?

干杯

【问题讨论】:

  • 第一列是否总是最多三个字段,用逗号分隔?

标签: mysql sql split


【解决方案1】:

我使用 CASE WHEN 来确定是否有 1 个或多个分号

SQL Fiddle Demo

SELECT 
  first,
  SUBSTRING_INDEX(first, ';', 1) AS 'a',
  CASE 
    WHEN LOCATE(';', first, 1) = 0 THEN NULL 
    ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(first, ';', 2), ';', -1)
  END AS 'b',
  CASE 
    WHEN LOCATE(';', first, 1) = 0 THEN NULL
    WHEN LOCATE(';', first, (LOCATE(';', first, 1) + 1)) = 0 THEN NULL
    ELSE SUBSTRING_INDEX(first, ';', -1)
  END AS 'c'
FROM new;

【讨论】:

    【解决方案2】:

    SQL Fiddle

    MySQL 5.5.32 架构设置

    CREATE TABLE new
        (`first` varchar(12))
    ;
    
    INSERT INTO new
        (`first`)
    VALUES
        ('ae;b;c'),
        ('d;ee;f'),
        ('g;he'),
        ('ie')
    ;
    

    查询 1

    SELECT 
      first,
      SUBSTRING_INDEX(first, ';', 1) AS 'a',
      CASE WHEN first LIKE '%;%;%' THEN 
                SUBSTRING_INDEX(SUBSTRING_INDEX(first, ';', 2), ';', -1) 
           WHEN first LIKE '%;%' THEN 
                SUBSTRING_INDEX(first, ';', -1)
           ELSE NULL END AS 'b',
      CASE WHEN first LIKE '%;%;%' THEN
                SUBSTRING_INDEX(first, ';', -1)
           ELSE NULL END AS 'c'
    FROM new
    

    Results

    |  FIRST |  A |      B |      C |
    |--------|----|--------|--------|
    | ae;b;c | ae |      b |      c |
    | d;ee;f |  d |     ee |      f |
    |   g;he |  g |     he | (null) |
    |     ie | ie | (null) | (null) |
    

    【讨论】:

      【解决方案3】:

      例如,您可以使用 Arman P 的 this 解决方案。

      创建一个函数 SPLIT_STRING 如链接所示,然后像这样调用它:

      先选择,SPLIT_STRING(first, ';', 1) as a, SPLIT_STRING(first, ';', 2) as b, SPLIT_STRING(first, ';', 3) as c

      【讨论】: