将具有多个值的MySql列转换为正确的表

时间:2014-10-27 21:17:08

标签: mysql sql

我有一个CSV文件形式的数据集,而不是定期发送给我的数据集。我想将这些数据导入MySql数据库并将其转换为一组适当的表。我遇到的问题是用于存储多个值的字段之一。例如,该字段存储电子邮件地址。它可能是一个电子邮件地址,也可能有两个,三个或四个等等。字段内容看起来像这样。 " USER1 @ domain.com,用户2 @ domain.com,用户3 @ domain.com"

我需要能够从每个字段中获取未确定数量的值,然后将它们添加到单独的表中,以便它们看起来像这样。

user1@domain.com  
user2@domain.com  
user3@domain.com

我不知道如何做到这一点。谢谢你的帮助。

4 个答案:

答案 0 :(得分:1)

最简单的方法可能是插入第一封电子邮件的蛮力方法,然后插入第二封电子邮件,依此类推:

insert into newtable(email)
    select substring_index(substring_index(emails, ',', 1), ',', -1)
    from emails
    where (length(replace(emails, ',', ',,')) - length(emails)) >= 1;

insert into newtable(email)
    select substring_index(substring_index(emails, ',', 2), ',', -1)
    from emails
    where (length(replace(emails, ',', ',,')) - length(emails)) >= 2;

insert into newtable(email)
    select substring_index(substring_index(emails, ',', 3), ',', -1)
    from emails
    where (length(replace(emails, ',', ',,')) - length(emails)) >= 3;

等等。

即,从列表中提取第n个元素并将其插入表中。 where子句计算列表中逗号的数量,该列表是列表长度的代理。

您需要重复此操作,直至列表中的最大电子邮件数。

答案 1 :(得分:0)

您可以使用PARSENAME功能,请参阅下面的示例

Select 'user1@domain.com,user1@domain.com,user1@domain.com' as value
INTO #NewTable1

Select  REPLACE(value,'.',':') 'value'    
INTO #NewTable2
from #NewTable1 

Select  REPLACE(value,',','.') 'value'    
INTO #NewTable3
from #NewTable2 

Select  value,
    PARSENAME(REPLACE(value,',','.'),1) 'val1',
    PARSENAME(REPLACE(value,',','.'),2) 'val2',
    PARSENAME(REPLACE(value,',','.'),3) 'val3' 
INTO #NewTable4
from #NewTable3 

SELECT * from #NewTable4

drop table #NewTable1
drop table #NewTable2
drop table #NewTable3
drop table #NewTable4

您唯一需要知道的是,如果数据不同,您可以尝试通过动态sql解决此问题的列中发生的数据的数量,在这种情况下,您需要为每次出现添加PARSENAME(REPLACE(value,',','.'),N) 'valN'

答案 2 :(得分:0)

我没有直接导入csv文件然后尝试修复其中的问题,而是发现攻击它的最佳方法是首先将csv传递给AWK。

AWK输出三个单独的csv文件,遵循正常形式。然后我导入那些表,一切都很顺利。

2 info="`ncftpget -V -c -u myuser -p mypassword ftp://fake.com/data_map.csv`"
3
4 echo "$info" | \
5 awk -F, -v OFS="," 'NR > 1 {
6   split($6, keyvalue, ";")
7     for (var in keyvalue) {
8       gsub(/.*:/, "", keyvalue[var])
9       print $1, keyvalue[var]
10 }}' > ~/sqlrw/table1.csv
11
12 echo "$info" | \
13 awk -F, -v OFS="," 'NR > 1 {
14   split($6, keyvalue, ";")
15     for (var in keyvalue) {
16       gsub(/:/, ",", keyvalue[var])
17       print keyvalue[var]
18 }}' > ~/sqlrw/table2.csv
19
20 sort -u ~/sqlrw/table2.csv -o ~/sqlrw/table2.csv
21
22 echo "$info" | \
23 awk -F, -v OFS="," 'NR > 1 {
24       print $1, $2, $3, $4, $5, $7, $8
25 }' > ~/sqlrw/table3.csv

答案 3 :(得分:0)

也许使用一个简单的PHP脚本/ shoud做的伎俩

<?php
    $file = file_get_contents("my_file.csv");
    $tmp = explode(";", $file); // iirc lines in csv are terminated by a ;

    for ($i=0; $i<count($tmp); $i++)
    {
        $field = $tmp[$i];

        $q = "INSERT INTO my_table (emails) VALUES (`$field`)";
        // or use $i as an id if don't have an autoincrement
        $q = "INSERT INTO my_table (id, emails) VALUES ($i, `$field`)";

       // execute query ....

    }
?>

希望这有助于即使它不是纯粹的SQL .....