44

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

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

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

productA, 12
productB, 71
productC, 92

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

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

4

3 回答 3

120

您可以使用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;
于 2012-04-20T21:25:46.017 回答
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.

于 2012-04-20T21:23:15.593 回答
1

@ike-walker 的回答确实是正确的,但也要记得仔细检查你的 CSV 数据是否格式化。很多时候,例如 CSV 文件可以包含用双引号括起来的字符串字段,如果在 Windows 上工作,则"行以结尾。 默认情况下,假定不使用任何封闭字符并且行尾是. 更多信息和示例在这里https://mariadb.com/kb/en/importing-data-into-mariadb/\r\n
\n

这可以通过使用附加选项来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;
于 2020-09-18T23:10:38.380 回答