Я нашел много примеров split-процедур для MySql, возвращающих x-часть строки. Но мне нужна сплит-процедура, чтобы вернуть ВСЕ части расщепленной строки, так что вроде как:
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)
Каков правильный способ сделать это?
Вы можете сделать это только с помощью простого 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
см. демо http://sqlfiddle.com/#!9/c314ca/20