MySQL: dividere l’elenco separato da virgole in più righe

Ho una tabella non normalizzata con una colonna contenente un elenco separato da virgole che è una chiave esterna a un’altra tabella:

+----------+-------------+ +--------------+-------+ | part_id | material | | material_id | name | +----------+-------------+ +--------------+-------+ | 339 | 1.2mm;1.6mm | | 1 | 1.2mm | | 970 | 1.6mm | | 2 | 1.6mm | +----------+-------------+ +--------------+-------+ 

Voglio leggere questi dati in un motore di ricerca che non offre un linguaggio procedurale.

Quindi c’è un modo per fare un join su questa colonna o eseguire una query su questi dati che inseriscono le voci appropriate in una nuova tabella? I dati risultanti dovrebbero apparire come questo:

 +---------+-------------+ | part_id | material_id | +---------+-------------+ | 339 | 1 | | 339 | 2 | | 970 | 2 | +---------+-------------+ 

Potrei pensare a una soluzione se il DBMS supportava le funzioni restituendo una tabella, ma apparentemente MySQL no.

In MySQL questo può essere ottenuto come di seguito

 SELECT id, length FROM vehicles WHERE id IN ( 117, 148, 126) +---------------+ | id | length | +---------------+ | 117 | 25 | | 126 | 8 | | 148 | 10 | +---------------+ SELECT id,vehicle_ids FROM load_plan_configs WHERE load_plan_configs.id =42 +---------------------+ | id | vehicle_ids | +---------------------+ | 42 | 117, 148, 126 | +---------------------+ 

Ora per ottenere la lunghezza della virgola separati vehicle_ids utilizzare sotto query

 Output SELECT length FROM vehicles, load_plan_configs WHERE load_plan_configs.id = 42 AND FIND_IN_SET( vehicles.id, load_plan_configs.vehicle_ids ) +---------+ | length | +---------+ | 25 | | 8 | | 10 | +---------+ 

Per maggiori informazioni visita http://amitbrothers.blogspot.in/2014/03/mysql-split-comma-separated-list-into.html

Ho risposto a due domande simili in tanti giorni ma non ho avuto alcuna risposta, quindi immagino che le persone siano scoraggiate dall’uso del cursore, ma come dovrebbe essere un processo a sé stante personalmente non penso che importi.

Come hai affermato, MySQL non supporta ancora i tipi di restituzione delle tabelle, quindi hai poche opzioni oltre a fare il ciclo della tabella e analizzare la stringa csv del materiale e generare le righe appropriate per la parte e il materiale.

I seguenti post possono essere di interesse:

parole chiave divise per post php mysql

Procedura MySQL per caricare i dati dalla tabella di staging ad altre tabelle. È necessario dividere il campo multivalore nel processo

Rgds

MySQL non ha il riutilizzo della tabella temporanea e le funzioni non restituiscono righe.

Non riesco a trovare nulla in Stack Overflow per convertire una stringa di interi csv in righe, quindi ho scritto il mio in MySQL.

 DELIMITER $$ DROP PROCEDURE IF EXISTS str_split $$ CREATE PROCEDURE str_split(IN str VARCHAR(4000),IN delim varchar(1)) begin DECLARE delimIdx int default 0; DECLARE charIdx int default 1; DECLARE rest_str varchar(4000) default ''; DECLARE store_str varchar(4000) default ''; create TEMPORARY table IF NOT EXISTS ids as (select parent_item_id from list_field where 1=0); truncate table ids; set @rest_str = str; set @delimIdx = LOCATE(delim,@rest_str); set @charIdx = 1; set @store_str = SUBSTRING(@rest_str,@charIdx,@delimIdx-1); set @rest_str = SUBSTRING(@rest_str from @delimIdx+1); if length(trim(@store_str)) = 0 then set @store_str = @rest_str; end if; INSERT INTO ids SELECT (@store_str + 0); WHILE @delimIdx <> 0 DO set @delimIdx = LOCATE(delim,@rest_str); set @charIdx = 1; set @store_str = SUBSTRING(@rest_str,@charIdx,@delimIdx-1); set @rest_str = SUBSTRING(@rest_str from @delimIdx+1); select @store_str; if length(trim(@store_str)) = 0 then set @store_str = @rest_str; end if; INSERT INTO ids(parent_item_id) SELECT (@store_str + 0);`enter code here` END WHILE; select parent_item_id from ids; end$$ DELIMITER ; call str_split('1,2,10,13,14',',') 

Dovrai anche eseguire il cast di tipi diversi se non stai usando ints.

È inoltre ansible utilizzare REGEXP

 SET @materialids=SELECT material FROM parttable where part_id=1; SELECT * FROM material_id WHERE REGEXP CONCAT('^',@materialids,'$'); 

Questo aiuterà se vuoi ottenere solo una parte. Non l’intero tavolo, naturalmente