我的列中包含可变数量的逗号分隔值:
somethingA,somethingB,somethingC
somethingElseA, somethingElseB
我希望结果取每个值,然后创建一行:
somethingA
somethingB
somethingC
somethingElseA
somethingElseB
我如何在SQL(MySQL)中执行此操作?
(我已经尝试使用谷歌搜索“内爆”和“横向视图”,但这些似乎没有出现相关问题。所有相关的SO问题都试图做更复杂的事情)
答案 0 :(得分: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
注意:诀窍是利用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
这是 SQLFiddle 演示