MySQL Split Comma Separated String Into Temp Table

È ansible analizzare una stringa separata da virgole in una tabella temporanea in MySQL utilizzando RegEx?

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

Questa è praticamente la stessa domanda di Can Mysql Split a column?

MySQL non ha una funzione di stringa divisa, quindi devi lavorare sul campo. Puoi fare qualsiasi cosa con i dati una volta divisi usando uno dei metodi elencati nella pagina di risposta sopra.

È ansible eseguire il loop su quella funzione personalizzata e interrompere quando restituisce vuoto, dovrete giocare e imparare qualche syntax (o almeno lo farei) ma la syntax per un ciclo FOR in mysql è qui: http: //www.roseindia .net / sql / mysql-example / for.shtml

Puoi scorrere su di esso, incrementando la posizione nella funzione seguente:

 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, ''); 

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

Quale dovrebbe restituire ” se non viene trovata alcuna corrispondenza, quindi interrompere il ciclo se non viene trovata alcuna corrispondenza. Ciò consentirà di analizzare solo mysql sulla stringa divisa ed eseguire le query di inserimento in una tabella temporanea. Ma uomo perché non usare un linguaggio di scripting come PHP per quel tipo di lavoro? 🙁

Codice per la syntax del loop:

 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 $$ 

Ho fatto questo, per quando non hai valori di tabella e così via:

 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; 

Potrebbe non essere la risposta migliore, ma funziona senza l'ausilio di funzioni e procedure, senza tabelle aggiuntive, ecc.

Puoi usare espressioni regolari in MySQL per specificare un modello per una ricerca complessa, non puoi analizzare le stringhe.

Ma puoi creare una query INSERT con l’aiuto di REPLACE e CONCATENATE per salvare i dati nella tabella temporanea.

 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 

Ho trovato una buona soluzione per questo

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

Grazie a Peter Brawley

Trucco: massaggiare un risultato Group_Concat () sulla stringa csv in una stringa Insert … Values ​​…:

 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 | +------+ 

Inoltre, se vuoi semplicemente unirti ad alcune tabelle per elencare id puoi usare l’operatore LIKE. C’è la mia soluzione in cui ottengo la lista di id da url post di blog, li converto in elenco separato da virgole iniziato e finito con virgole e poi unisco i prodotti correlati dalla lista id con operatore 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 != '' 

Se il testo che si sta tentando di suddividere contiene caratteri a più byte, questo approccio si interromperà a causa del calcolo errato di LUNGHEZZA. Per questi casi, la seguente versione con CHAR_LENGTH invece di LENGTH funziona:

 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 

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

Solo perché amo davvero resuscitare vecchie domande:

 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 

Quale produce:

 P1 1 2 3 4 

Quando si utilizza CALL SPLIT_LIST_STR('("', '")', '("1", "2", "3", "4")', '", "');

Potrei apparire più tardi per aggiornare il codice un po ‘di più! Saluti!