我发现很多MySql拆分过程的例子都返回了字符串的xth部分。但我需要一个拆分程序来返回拆分字符串的所有部分,所以像:
SELECT split(",", "1,2,3,4,5,6");
应该返回;
+-------+
| split |
+-------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+-------+
我试过了:
DELIMITER $$
CREATE PROCEDURE `split`(delimeter VARCHAR(1),txt VARCHAR(65535))
RETURNS split TABLE (
part varchar(1024) NOT NULL)
DETERMINISTIC
BEGIN
DECLARE pos, posOld;
set pos := locate(delimeter,txt);
set posOld = 1;
WHILE pos > 0 DO
set part := subst(text, posOld, pos-1);
set posOld := pos+1;
insert into split (`part`) values (part);
set pos := locate(delimeter, txt, posOld);
END WHILE;
END$$
但得到错误:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'split TABLE (part varchar(1024) NOT NULL)
这是正确的方法吗?
答案 0 :(得分:2)
您只能使用纯SQL执行此操作。
这个技巧是将MySQL数字生成器与嵌套的SUBSTRING_INDEX函数结合使用。
<强>查询强>
此查询将生成1到100之间的数字 因此,最终查询最多可支持100个分隔值。
SELECT
(@number := @number + 1) AS number
FROM (
SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_1
CROSS JOIN (
SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_2
CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
参见演示http://sqlfiddle.com/#!9/c314ca/5
现在我们将使用
从逗号分隔的字符串中提取值<强>查询强>
将[position]替换为0 - 5中要从逗号分隔字符串中提取的值。
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('1,2,3,4,5', ',', [position]), ',', -1) AS split;
参见演示http://sqlfiddle.com/#!9/c314ca/16
现在我们知道了将两个查询结合到工作解决方案的基础知识。
<强>查询强>
SELECT
DISTINCT
SUBSTRING_INDEX(SUBSTRING_INDEX(@CSV, ',', generator.number), ',', -1) AS split
FROM (
SELECT
(@number := @number + 1) AS number
FROM (
SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_1
CROSS JOIN (
SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_2
CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
)
AS generator
CROSS JOIN (
SELECT @CSV := '1,2,3,4,5'
) AS init_user_param