SQL拆分逗号分隔行

Don*_*n P 20 mysql sql hive

我有一个包含可变数量的逗号分隔值的列:

somethingA,somethingB,somethingC
somethingElseA, somethingElseB
Run Code Online (Sandbox Code Playgroud)

我希望结果取每个值,并创建一行:

somethingA
somethingB
somethingC
somethingElseA
somethingElseB
Run Code Online (Sandbox Code Playgroud)

我怎么能在SQL(MySQL)中这样做?

(我试过谷歌搜索"内爆"和"侧视图",但那些似乎没有出现相关的问题.所有相关的SO问题都试图做更复杂的事情)

pet*_*erm 64

您可以使用纯SQL这样做

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.values, ',', n.n), ',', -1) value
  FROM table1 t CROSS JOIN 
(
   SELECT a.N + b.N * 10 + 1 n
     FROM 
    (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
   ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
    ORDER BY n
) n
 WHERE n.n <= 1 + (LENGTH(t.values) - LENGTH(REPLACE(t.values, ',', '')))
 ORDER BY value
Run Code Online (Sandbox Code Playgroud)

注意:诀窍是利用tally(数字)表,在这种情况下MySQL函数非常方便SUBSTRING_INDEX().如果你做了很多这样的查询(拆分),那么你可能会考虑填充并使用一个持久的计数表,而不是像本例中那样使用子查询生成它.此示例中的子查询生成一个从1到100的数字序列,有效地允许您在源表中每行最多分割100个分隔值.如果您需要更多或更少,您可以轻松调整它.

输出:

|          VALUE |
|----------------|
|     somethingA |
|     somethingB |
|     somethingC |
| somethingElseA |
| somethingElseB |

这是SQLFiddle演示


这是查询在持久计数表中的外观

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.values, ',', n.n), ',', -1) value
  FROM table1 t CROSS JOIN tally n
 WHERE n.n <= 1 + (LENGTH(t.values) - LENGTH(REPLACE(t.values, ',', '')))
 ORDER BY value
Run Code Online (Sandbox Code Playgroud)

这是SQLFiddle演示