我有一个看起来像这样的表:
products
--------
id, product, sku, department, quantity
此表中约有800,000个条目。我收到了一个新的CSV文件,用于更新每种产品的所有数量,例如:
productA, 12
productB, 71
productC, 92
因此,大约有750,000个更新(50,000个产品的数量没有变化)。
我的问题是,如何导入此CSV以仅更新基于product
(唯一)的数量,但仅保留sku
,department
和其他字段?我知道如何通过循环CSV并为每一行执行更新来在PHP中执行此操作,但这似乎效率低下。
答案 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/
可以通过为FIELDS
和LINES
使用附加选项来解决此问题
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;