MySQL:将逗号分隔的列表分成多行

我有一个非正规化的表,其中包含一个逗号分隔的列,这是另一个表的外键:

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

我想将这些数据读入不提供过程语言的search引擎。

那么是否有办法在这个列上build立一个连接, 或者在这个数据上运行一个查询来插入适当的条目到一个新的表中? 结果数据应该如下所示:

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

如果DBMS支持函数返回一个表,但是MySQL显然不支持,我可以考虑一个解决scheme。

在MySQL中,这可以实现如下

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

现在得到逗号分隔的vehicle_ids的长度用下面的查询

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

欲了解更多信息,请访问http://amitbrothers.blogspot.in/2014/03/mysql-split-comma-separated-list-into.html

我已经在很多天里回答了两个类似的问题,但没有任何回应,所以我猜人们会因为使用光标而被拖延,但是因为它应该是一个一次性的过程,所以我个人不认为这很重要。

正如你所说MySQL不支持表返回types,所以除了循环表和parsing材质csvstring并为零件和材质生成适当的行以外,没有其他select。

以下post可能会引起您的兴趣:

拆分关键字后的PHP MySQL

将数据从临时表加载到其他表的MySQL过程。 在这个过程中需要分割多个字段

RGDS

MySQL没有临时表重用,函数不返回行。

我无法find任何堆栈溢出将csv整数string转换成行,所以我写了我自己的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',',') 

如果您不使用整数,您还需要投射到不同的types。

您也可以使用REGEXP

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

这将有助于如果你只想得到一个部分。 当然不是整个桌子