44 votes

Importer un CSV pour mettre à jour une seule colonne d'un tableau

J'ai un tableau qui ressemble à ceci :

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

Il y a environ 800 000 entrées dans cette table. J'ai reçu un nouveau fichier CSV qui met à jour toutes les quantités de chaque produit, par exemple :

productA, 12
productB, 71
productC, 92

Il y a donc environ 750 000 mises à jour (50 000 produits dont la quantité n'a pas changé).

Ma question est la suivante : comment puis-je importer ce CSV pour mettre à jour uniquement la quantité sur la base de l'adresse de l'entreprise ? product (unique) mais laissez le sku , department et d'autres domaines seulement ? Je sais comment faire cela en PHP en bouclant le CSV et en exécutant une mise à jour pour chaque ligne, mais cela semble inefficace.

121voto

Ike Walker Points 21162

Vous pouvez utiliser LOAD DATA INFILE pour charger en masse les 800 000 lignes de données dans une table temporaire, puis utiliser des tables multiples. UPDATE syntaxe pour joindre votre table existante à la table temporaire et mettre à jour les valeurs de quantité.

Par exemple :

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;

4 votes

Génial - C'est une réponse vraiment sophistiquée !

0 votes

@lke Walker, pouvez-vous répondre à ma question ? stackoverflow.com/questions/21495600/

2 votes

Au lieu de la section "CHARGER LES DONNÉES", vous pouvez utiliser la fonction "Importer" de phpMyAdmin si vous préférez, puis utiliser la section "MISE À JOUR" de cette réponse.

5voto

DocJones Points 587

Je chargerais les données de mise à jour dans une table séparée. UPDATE_TABLE et effectuer une mise à jour dans MySQL en utilisant :

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

Je n'ai pas de MySQL sous la main pour le moment, je peux donc vérifier la syntaxe parfaitement, il se peut que vous ayez besoin d'ajouter un LIMIT 0,1 à l'intérieur SELECT .

1voto

Gruber Points 361

La réponse de @ike-walker est en effet correcte mais n'oubliez pas de vérifier le format de vos données CSV. Souvent, par exemple, les fichiers CSV peuvent contenir des chaînes de caractères entre guillemets. " et les lignes se terminant par \r\n si vous travaillez sous Windows.
Par défaut, il est supposé qu'aucun caractère de clôture n'est utilisé et que la fin de ligne est \n . Plus d'informations et d'exemples ici https://mariadb.com/kb/en/importing-data-into-mariadb/

Cela peut être corrigé en utilisant des options supplémentaires pour FIELDS y 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;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X