2010-11-17 74 views
2

我有一个旧的数据库与一个极大的记录(或多或少)具有单个标签栏(与标签被管道分隔),看起来像这样:如何拆分Pipe-Delimited列并将每个值插入到新表中一次?

Breakfast 
    Breakfast|Brunch|Buffet|Burger|Cakes|Crepes|Deli|Dessert|Dim Sum|Fast Food|Fine Wine|Spirits|Kebab|Noodles|Organic|Pizza|Salad|Seafood|Steakhouse|Sushi|Tapas|Vegetarian 
    Breakfast|Brunch|Buffet|Burger|Deli|Dessert|Fast Food|Fine Wine|Spirits|Noodles|Pizza|Salad|Seafood|Steakhouse|Vegetarian 
    Breakfast|Brunch|Buffet|Cakes|Crepes|Dessert|Fine Wine|Spirits|Salad|Seafood|Steakhouse|Tapas|Teahouse 
    Breakfast|Brunch|Burger|Crepes|Salad 
    Breakfast|Brunch|Cakes|Dessert|Dim Sum|Noodles|Pizza|Salad|Seafood|Steakhouse|Vegetarian 
    Breakfast|Brunch|Cakes|Dessert|Dim Sum|Noodles|Pizza|Salad|Seafood|Vegetarian 
    Breakfast|Brunch|Deli|Dessert|Organic|Salad 
    Breakfast|Brunch|Dessert|Dim Sum|Hot Pot|Seafood 
    Breakfast|Brunch|Dessert|Dim Sum|Seafood 
    Breakfast|Brunch|Dessert|Fine Wine|Spirits|Noodles|Pizza|Salad|Seafood 
    Breakfast|Brunch|Dessert|Fine Wine|Spirits|Salad|Vegetarian 

有没有办法一个可以检索各标记并将其插入仅使用MySQL的新表tag_id | tag_nm

+0

的值是管道分隔? – 2010-11-17 04:45:49

+0

是的,这代表了20个collumns中的一个 – Moak 2010-11-17 04:46:52

+0

你不能只是获取数据,例如,使用PHP的str_replace()并生成转储文件? – 2010-11-17 04:50:14

回答

1

发现后没有正式的分裂功能我已经解决了使用MySQL的只有像这样的问题:

1:我创建了功能strSplit

CREATE FUNCTION strSplit(x varchar(21845), delim varchar(255), pos int) returns varchar(255) 
return replace(
replace(
substring_index(x, delim, pos), 
substring_index(x, delim, pos - 1), 
'' 
), 
delim, 
'' 
); 

其次,我插入新将标签粘贴到我的新表中(真实姓名和栏目已更改,以保持简单)

INSERT IGNORE INTO tag (SELECT null, strSplit(`Tag`,'|',1) AS T FROM `old_venue` GROUP BY T) 

冲洗和重复一个每个collumn增加POS(在这种情况下,我有一个最大的8个分隔符的)

三得到的关系

INSERT INTO `venue_tag_rel` 
(Select a.`venue_id`, b.`tag_id` from `old_venue` a, `tag` b 
    WHERE 
    (   
    a.`Tag` LIKE CONCAT('%|',b.`tag_nm`) 
    OR a.`Tag` LIKE CONCAT(b.`tag_nm`,'|%') 
    OR a.`Tag` LIKE CONCAT(CONCAT('%|',b.`tag_nm`),'|%') 
    OR a.`Tag` LIKE b.`tag_nm` 
    ) 
) 
2

这里是我使用PHP的尝试...,我想这可以更聪明的MySQL查询更有效。我也把它的关系部分放在那里。没有逃脱和错误检查。

$rs = mysql_query('SELECT `venue_id`, `tag` FROM `venue` AS a'); 
while ($row = mysql_fetch_array($rs)) { 
    $tag_array = explode('|',$row['tag']); 
    $venueid = $row['venue_id']; 
    foreach ($tag_array as $tag) { 
     $rs2 = mysql_query("SELECT `tag_id` FROM `tag` WHERE tag_nm = '$tag'"); 
     $tagid = 0; 
     while ($row2 = mysql_fetch_array($rs2)) $tagid = $row2['tag_id']; 
     if (!$tagid) { 
      mysql_execute("INSERT INTO `tag` (`tag_nm`) VALUES ('$tag')"); 
      $tagid = mysql_insert_id; 
     } 
     mysql_execute("INSERT INTO `venue_tag_rel` (`venue_id`, `tag_id`) VALUES ($venueid, $tagid)"); 
    } 
} 
+0

+1是的,就像这样。我认为开发一个PHP脚本(或者其他任何真正的语言)要比在SQL代码中完成这些工作更容易开发和调试。 – 2010-11-17 06:10:20

+0

但这只能解决PHP程序员的问题。我添加了一个MYSQL答案供将来参考。 +1回答,但没有经过测试 – Moak 2010-11-17 06:17:09

相关问题