2010-10-14 51 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',',') 

如果您不使用整數,您還需要轉換爲不同的類型。