MySQL Split Comma Separated String en la tabla Temp

¿Se puede analizar una cadena separada por comas en una tabla temporal en MySQL usando RegEx?

'1|2|5|6' into temp table with 4 rows. 

Esta es más o menos la misma pregunta que Can Mysql ¿Dividir una columna?

MySQL no tiene una función de cadena dividida, por lo que debe hacer todo lo posible. Puede hacer cualquier cosa con los datos una vez que los divida utilizando uno de los métodos enumerados en la página de respuestas anterior.

Puedes recorrer esa función personalizada y romperla cuando vuelva vacía, tendrás que jugar y aprender alguna syntax (o al menos yo), pero la syntax de un bucle FOR en mysql está aquí: http: //www.roseindia .net / sql / mysql-example / for.shtml

Puede iterar sobre él, incrementando la posición en la función a continuación:

 CREATE FUNCTION SPLIT_STR( x VARCHAR(255), delim VARCHAR(12), pos INT ) RETURNS VARCHAR(255) RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos), LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1), delim, ''); 

(Crédito: https://blog.fedecarg.com/2009/02/22/mysql-split-string-function/ )

Que debería regresar ” si no se encuentra una coincidencia, por lo que rompa el ciclo si no se encuentra una coincidencia. Esto le permitirá analizar solo mysql sobre la cadena dividida y ejecutar las consultas insertadas en una tabla temporal. Pero, ¿por qué no usar un lenguaje de scripting como php para ese tipo de trabajo? 🙁

Código para syntax de bucle:

 DELIMITER $$ CREATE PROCEDURE ABC(fullstr) BEGIN DECLARE a INT Default 0 ; DECLARE str VARCHAR(255); simple_loop: LOOP SET a=a+1; SET str=SPLIT_STR(fullstr,"|",a); IF str='' THEN LEAVE simple_loop; END IF; #Do Inserts into temp table here with str going into the row insert into my_temp_table values (str); END LOOP simple_loop; END $$ 

He hecho esto, porque cuando no tienes valores de tabla, etc.

 select * from( select c, SUBSTRING_INDEX(SUBSTRING_INDEX('1|2|5|6', '|', c+1), '|', -1) as name from( SELECT (TWO_1.SeqValue + TWO_2.SeqValue + TWO_4.SeqValue + TWO_8.SeqValue + TWO_16.SeqValue + TWO_32.SeqValue) c FROM ( SELECT 0 SeqValue UNION ALL SELECT 1 SeqValue) TWO_1 CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 2 SeqValue) TWO_2 CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 4 SeqValue) TWO_4 CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 8 SeqValue) TWO_8 CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 16 SeqValue) TWO_16 CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 32 SeqValue) TWO_32 ) as b WHERE c <= (CHAR_LENGTH('1|2|5|6') - CHAR_LENGTH(REPLACE('1|2|5|6', '|', ''))) ) as a; 

Puede que no sea la mejor respuesta, pero funciona sin ayuda de funciones y procedimientos, sin tablas adicionales, etc.

Puede usar expresiones regulares en MySQL para especificar un patrón para una búsqueda compleja, no puede analizar las cadenas.

Pero puede crear consultas INSERT con la ayuda de REEMPLAZAR y CONCATENAR para guardar datos en la tabla temporal.

 DELIMITER $$ CREATE PROCEDURE SPLIT_VALUE_STRING() BEGIN SET @String = '1,22,333,444,5555,66666,777777'; SET @Occurrences = LENGTH(@String) - LENGTH(REPLACE(@String, ',', '')); myloop: WHILE (@Occurrences > 0) DO SET @myValue = SUBSTRING_INDEX(@String, ',', 1); IF (@myValue != '') THEN /* my code... */ ELSE LEAVE myloop; END IF; SET @Occurrences = LENGTH(@String) - LENGTH(REPLACE(@String, ',', '')); IF (@occurrences = 0) THEN LEAVE myloop; END IF; SET @String = SUBSTRING(@String,LENGTH(SUBSTRING_INDEX(@String, ',', 1))+2); END WHILE; END $$ 
 select distinct SUBSTRING_INDEX(SUBSTRING_INDEX('1,2,3,4', ',', numbers.n), ',', -1) name from (select @rownum := @rownum + 1 as n from YourTable cross join (select @rownum := 0) r ) numbers order by n 

Encontré una buena solución para esto

https://forums.mysql.com/read.php?10,635524,635529

Gracias a Peter Brawley

Truco: masajear un resultado de Group_Concat () en la cadena csv en una cadena Insertar … Valores …

 drop table if exists t; create table t( txt text ); insert into t values('1,2,3,4,5,6,7,8,9'); drop temporary table if exists temp; create temporary table temp( val char(255) ); set @sql = concat("insert into temp (val) values ('", replace(( select group_concat(distinct txt) as data from t), ",", "'),('"),"');"); prepare stmt1 from @sql; execute stmt1; select distinct(val) from temp; +------+ | val | +------+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | +------+ 

Además, si solo quiere unirse a una tabla para listar su id, puede usar el operador LIKE. Existe mi solución en la que obtengo una lista de id. De URL de publicación de blog, los convierto en una lista separada por comas iniciada y terminada con comas y luego unir productos relacionados por lista de identificación con el operador LIKE.

 SELECT b2.id blog_id, b2.id_list, p.id FROM ( SELECT b.id,b.text, CONCAT( ",", REPLACE( EXTRACTVALUE(b.text,'//a/@id') , " ", "," ) ,"," ) AS id_list FROM blog b ) b2 LEFT JOIN production p ON b2.id_list LIKE CONCAT('%,',p.id,',%') HAVING b2.id_list != '' 

Si el texto que intenta dividir contiene caracteres de varios bytes, este enfoque se descompondrá debido a que la LONGITUD se calcula incorrectamente. Para tales casos, la siguiente versión con CHAR_LENGTH en lugar de LENGTH funciona:

 CREATE DEFINER=`root`@`localhost` FUNCTION `strSplit`( `src` MEDIUMTEXT CHARACTER SET utf8, `delim` VARCHAR(12), `pos` INTEGER ) RETURNS mediumtext LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN DECLARE output MEDIUMTEXT CHARACTER SET utf8; SET output = REPLACE(SUBSTRING(SUBSTRING_INDEX(src, delim, pos) , CHAR_LENGTH(SUBSTRING_INDEX(src, delim, pos - 1)) + 1) , delim , ''); IF output = '' THEN SET output = null; END IF; RETURN output; END 

Referencia: http://www.shakedos.com/2011/Nov/23/mysql-split-string-function-fix-split_str.html

Solo porque me encanta resucitar viejas preguntas:

 CREATE PROCEDURE `SPLIT_LIST_STR`(IN `INISTR` TEXT CHARSET utf8mb4, IN `ENDSTR` TEXT CHARSET utf8mb4, IN `INPUTSTR` TEXT CHARSET utf8mb4, IN `SEPARATR` TEXT CHARSET utf8mb4) BEGIN SET @I = 1; SET @SEP = SEPARATR; SET @INI = INISTR; SET @END = ENDSTR; SET @VARSTR = REPLACE(REPLACE(INPUTSTR, @INI, ''), @END, ''); SET @N = FORMAT((LENGTH(@VARSTR)-LENGTH(REPLACE(@VARSTR, @SEP, '')))/LENGTH(@SEP), 0)+1; CREATE TEMPORARY TABLE IF NOT EXISTS temp_table(P1 TEXT NULL); label1: LOOP SET @TEMP = SUBSTRING_INDEX(@VARSTR, @SEP, 1); insert into temp_table (`P1`) SELECT @TEMP; SET @I = @I + 1; SET @VARSTR = REPLACE(@VARSTR, CONCAT(@TEMP, @SEP), ''); IF @N >= @I THEN ITERATE label1; END IF; LEAVE label1; END LOOP label1; SELECT * FROM temp_table; END 

Que produce:

 P1 1 2 3 4 

Al usar CALL SPLIT_LIST_STR('("', '")', '("1", "2", "3", "4")', '", "');

¡Podría aparecer más tarde para mejorar el código un poco más! ¡Aclamaciones!