【问题标题】:PHP and MySQL: Import CSV using Column Value as tablePHP 和 MySQL:使用列值作为表导入 CSV
【发布时间】:2013-02-04 16:26:35
【问题描述】:

我已将我当前的代码(不多)放在此页面上供您参考(当然要减去真实密码):http://mafgiftshop.org/MAF/queue/MP/for-reference.php

    $delimiter = ',';
$db = new mysqli('localhost', 'mafgifts_mp', '******', 'mafgifts_mp');

if (($handle = fopen("mpdata.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
        foreach($data as $i => $content) {
            $data[$i] = $db->real_escape_string($content);
        }
        echo $data[$i]."";
        $db->query("INSERT INTO `MP` 
                      (GiftAmount,GoalAmount,GiftDate,FundID,FundDescription) 
                      VALUES('" . implode("','", $data) . "');");
    }
    fclose($handle);
}

//THE ABOVE CODE PROPERLY PUTS ALL THE DATA INTO THE MySQL DATABASE, BUT I'M NOT 
//ABLE TO DO THE CALCULATIONS I WANT AND INSERT ONLY THE RESULTING DATA.

所以我有一个包含 5 列信息的 CSV 文件。没有空白值。例如:

GiftAmount,GoalAmount,GiftDate,FundID,FundDescription(CSV 中没有此行,仅供参考)

  • "$10","$500","1/1/2012","8008","8008 基金说明"
  • "$20","$500","2/10/2012","8008","8008 基金说明"
  • "$62","$500","1/12/2012","8008","8008 基金说明"
  • "$38","$1,000","3/31/2012","9102","9102 基金说明"
  • "$21","$1,000","4/6/2012","9102","9102 基金说明"

我需要做的是在 FundID 相同的情况下添加“GiftAmount”列,并将结果放入 MySQL 数据库。因此,对于上述数据,这将是生成的 MySQL 表:

  • "$92" | “500 美元” | 《8008》 | “8008 基金说明”(请注意不再需要 GiftDate)
  • “59 美元”| “1,000 美元” | “9102” | 《9102基金说明》

我正在使用 PHP 来完成此操作,PHP 文件将每天在 Cron 作业中运行,因为 CSV 文件会根据不同基金的新礼物每天更改。

顺便说一句,CSV 文件目前有 8,794 行和很多很多 FundID。

【问题讨论】:

  • 看起来你只需要一个SUM(GiftAmount) 和一个GROUP BY。您使用的是什么查询?
  • @njk 它来自 csv 而不是 mysql 数据库。
  • 你可以做两件事之一。在 PHP 方面,如果它是同一个基金,则会添加设置逻辑。这仅在它是顺序的情况下才有效,否则您将需要一个数组。在 SQL 端,您创建一个临时表,在那里执行计算并插入到生产表中。

标签: php mysql database csv import


【解决方案1】:

我会将 FundID 设为 MYSQL 中的唯一键,然后使用 INSERT INTO ... ON DUPLICATE KEY UPDATE 查询。

    $db->query("INSERT INTO `MP` (GiftAmount,GoalAmount,GiftDate,FundID,FundDescription) VALUES('" . implode("','", $data) . "') ON DUPLICATE KEY UPDATE GiftAmount=GiftAmount+".intval($data[0]).";");

这假设 GiftAmount 是一个数字列,并且您没有将其存储为字符串。

【讨论】:

  • 非常感谢您的快速回复。您提到了 GiftAmount 是数字的假设。在 CSV 中,它只是一个字符串。如何在循环中将其转换为小数(对吗?)?
  • intval($data[0]) 更改为sscanf($data[0], "\$%f")
  • 这是我的查询到目前为止的样子:$db->query("INSERT INTO MP (GiftAmount,GoalAmount,GiftDate,FundID,FundDescription) VALUES('" . implode("','", $data) . "') ON DUPLICATE KEY UPDATE GiftAmount=GiftAmount+".sscanf($data[0], "\$%f").";"); 这不会将数据放入数据库中。我在我的文本编辑器中注意到 ON DUPLICATE KEY UPDATE 似乎是用颜色编码的,就好像它在引号内一样。不过,我不确定这是否是问题所在。
  • 这是我的 PHPMyAdmin 的截图,以防万一:mafgiftshop.org/MAF/queue/MP/phpmyadmin.jpg
  • 好的,我越来越近了:$db->query("INSERT INTO MP (GiftAmount,GoalAmount,GiftDate,FundID,FundDescription) VALUES('" . implode("','", $data) . "') ON DUPLICATE KEY UPDATE GiftAmount=GiftAmount+".floatval(preg_replace("/[^-0-9\.]/","",$data[0])).";"); 不幸的是,计算似乎使组中的第一个数字加倍(在我上面的示例中,8008 FundID 组的总数为 102,因为它添加了先给自己 10 美元,然后再添加其余的。关于为什么会发生这种情况的任何想法?
猜你喜欢
  • 2019-08-06
  • 1970-01-01
  • 2017-10-02
  • 1970-01-01
  • 2019-04-16
  • 2012-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多