2010-10-14 95 views
14

我有一个非标准化表包含逗号分隔列表的列是一个外键到另一个表:MySQL的:拆分逗号分开成多行

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

我想读这个数据到搜索不提供过程语言的引擎。

那么,有没有办法既使在此列运行该数据插入相应的条目到一个新表的查询的加入? 得到的数据应该是这样的:

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

我能想到的解决方案,如果DBMS支持返回表功能,但MySQL的显然不会。

回答

9

的整个表在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  | 
+---------+ 

For more info visit http://amitbrothers.blogspot.in/2014/03/mysql-split-comma-separated-list-into.html

+0

如此有帮助,我正在处理某些列中的CSV数据的数据库 – lintuxvi 2016-01-21 19:16:49

5

我已经回答了在许多天两个类似的问题,但让我猜人们通过使用游标推迟没有任何反应,但因为它应该是一次性的过程中,我个人不认为事情。

正如你所说的MySQL犯规支持台返回类型,因此还具有比回路表几乎没有其它选择和分析材料CSV字符串,并产生部分和材料相应的行。

下面的帖子可以证明的兴趣:

split keywords for post php mysql

MySQL procedure to load data from staging table to other tables. Need to split up multivalue field in the process

RGDS

+0

不知道你是否可以在没有循环的情况下做到这一点,除非预设的最大数量的值可以在逗号分隔值中......你有点被迫循环 – Twelfth 2010-10-14 18:49:32

+0

是的,你必须循环 - 如上所述。 – 2010-10-14 19:01:44

+0

不是最好的解决方案,因为它将问题从设置的理论级别提升到程序级别,因此只能用于准备,而不是实时(回答我的“或”,而不是我的“任一”问题),但至少可以工作。谢谢。 :) – AndreKR 2010-10-15 07:36:20

0

您还可以使用REGEXP

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

这将帮助,如果你想得到一个pa RT。当然不是

+6

感谢你的回答,但我认为你的SQL根本没有意义。 :) – AndreKR 2011-07-28 15:13:40

1

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

我找不到堆栈溢出什么CSV整数字符串转换为行,所以我写了我自己在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',',') 

如果您不使用整数,您还需要转换为不同的类型。