Mysql 导入CSV以仅更新表中的一列

Mysql 导入CSV以仅更新表中的一列,mysql,csv,import,Mysql,Csv,Import,我有一张这样的桌子: products -------- id, product, sku, department, quantity 此表中大约有800000个条目。我收到了一个新的CSV文件,该文件更新了每个产品的所有数量,例如: productA, 12 productB, 71 productC, 92 CREATE TEMPORARY TABLE your_temp_table LIKE your_table; LOAD DATA INFILE '/tmp/your_file.c

我有一张这样的桌子:

products
--------
id, product, sku, department, quantity
此表中大约有800000个条目。我收到了一个新的CSV文件,该文件更新了每个产品的所有数量,例如:

productA, 12
productB, 71
productC, 92
CREATE TEMPORARY TABLE your_temp_table LIKE your_table;

LOAD DATA INFILE '/tmp/your_file.csv'
INTO TABLE your_temp_table
FIELDS TERMINATED BY ','
(id, product, sku, department, quantity); 

UPDATE your_table
INNER JOIN your_temp_table on your_temp_table.id = your_table.id
SET your_table.quantity = your_temp_table.quantity;

DROP TEMPORARY TABLE your_temp_table;
因此,大约有750000个更新(50000个产品的数量没有变化)


我的问题是,如何导入此CSV以仅更新基于
产品(唯一)的数量,而不使用
sku
部门
和其他字段?我知道如何在PHP中通过CSV循环并对每一行执行更新来实现这一点,但这似乎效率低下。

我会将更新数据加载到一个单独的表
update\u table
中,并使用以下方法在MySQL中执行更新:

UPDATE PRODUCTS P SET P.QUANTITY=(
    SELECT UPDATE_QUANTITY
    FROM UPDATE_TABLE
    WHERE UPDATE_PRODUCT=P.PRODUCT
)
我现在手头没有MySQL,所以我可以很好地检查语法,可能您需要在内部
SELECT

中添加
LIMIT 0,1
,您可以使用它将800000行数据批量加载到临时表中,然后使用多表语法将现有表连接到临时表,并更新数量值

例如:

productA, 12
productB, 71
productC, 92
CREATE TEMPORARY TABLE your_temp_table LIKE your_table;

LOAD DATA INFILE '/tmp/your_file.csv'
INTO TABLE your_temp_table
FIELDS TERMINATED BY ','
(id, product, sku, department, quantity); 

UPDATE your_table
INNER JOIN your_temp_table on your_temp_table.id = your_table.id
SET your_table.quantity = your_temp_table.quantity;

DROP TEMPORARY TABLE your_temp_table;

@ike walker的回答确实正确,但也请记住,如果您的CSV数据已格式化,请再次检查其格式。例如,在许多情况下,如果在Windows上工作,CSV文件中的字符串字段可以用双引号括起来。
,并且行的结尾可以是
\r\n

默认情况下,假定不使用封闭字符,行尾为
\n
。 更多信息和例子在这里

这可以通过使用
字段

CREATE TEMPORARY TABLE your_temp_table LIKE your_table;

LOAD DATA INFILE '/tmp/your_file.csv'
INTO TABLE your_temp_table
FIELDS 
   TERMINATED BY ','            
   OPTIONALLY ENCLOSED BY '"'    -- new option
LINES TERMINATED BY '\r\n'       -- new option

(id, product, sku, department, quantity); 

UPDATE your_table
INNER JOIN your_temp_table on your_temp_table.id = your_table.id
SET your_table.quantity = your_temp_table.quantity;

DROP TEMPORARY TABLE your_temp_table;

太棒了-这是一个非常复杂的答案!@lke Walker,你能回答我的这个问题吗?你可以使用phpMyAdmin的“导入”而不是“加载数据”部分函数,然后使用此答案的“更新”部分。如果临时表数据与主表数据不完全匹配,则与上面的答案有关系吗?例如,如果CSV文件包含50000行数据,但主表包含200000行数据。这个方法会忽略列id不匹配的行吗?另外,如果CSV文件包含新行怎么办?是否可以通过修改上述函数添加新行?我使用LOAD DATA LOCAL Infle将数据发送到远程服务器(例如Amazon RDS)