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

时间:2012-04-20 21:11:12

标签: mysql csv import

我有一个看起来像这样的表:

products
--------
id, product, sku, department, quantity

此表中约有800,000个条目。我收到了一个新的CSV文件,用于更新每种产品的所有数量,例如:

productA, 12
productB, 71
productC, 92

因此,大约有750,000个更新(50,000个产品的数量没有变化)。

我的问题是,如何导入此CSV以仅更新基于product(唯一)的数量,但仅保留skudepartment和其他字段?我知道如何通过循环CSV并为每一行执行更新来在PHP中执行此操作,但这似乎效率低下。

3 个答案:

答案 0 :(得分:114)

您可以使用LOAD DATA INFILE将800,000行数据批量加载到临时表中,然后使用多表UPDATE语法将现有表连接到临时表并更新数量值。

例如:

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;

答案 1 :(得分:5)

我会将更新数据加载到单独的表UPDATE_TABLE中并使用以下命令在MySQL中执行更新:

UPDATE PRODUCTS P SET P.QUANTITY=(
    SELECT UPDATE_QUANTITY
    FROM UPDATE_TABLE
    WHERE UPDATE_PRODUCT=P.PRODUCT
)

我现在手头没有MySQL,所以我可以完美地检查语法,可能需要在内部LIMIT 0,1添加SELECT

答案 2 :(得分:0)

@ ike-walker的回答确实是正确的,但也请记住要仔细检查CSV数据(如果格式化)的方式。例如,在Windows上,很多时候CSV文件中的字符串字段都可以用双引号"括起来,而以\r\n结尾的行也可以使用。
默认情况下,假定不使用任何封闭字符,并且行尾为\n。 更多信息和示例,请点击此处https://mariadb.com/kb/en/importing-data-into-mariadb/

可以通过为FIELDSLINES使用附加选项来解决此问题

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;