Mettre à jour plusieurs lignes d'un tableau avec une seule instruction?

9

Quelle est la façon la plus simple de mettre à jour de nombreuses lignes dans une table? J'ai un fichier csv qui ressemble à ceci:

|primary_key |value|
|          1 |  xyz|
|          2 |  abc|
|          3 |  def|
...

Les lignes avec ces clés primaires existent déjà dans la table cible

Je voudrais mettre à jour la table cible avec ces valeurs. Existe-t-il une syntaxe pour que je puisse écrire quelque chose comme:

update mytable set value = ('xyz', 'abc', 'def') where primary key = (1,2,3);

En parcourant la référence de mise à jour MySQL , ce site ( mise à jour MySQL - csv ), SO ( mise à jour de plusieurs lignes , plusieurs mises à jour de base de données , mise à jour de plusieurs lignes ), je soupçonne que la réponse est "non", mais je voudrais confirmer que cela est vrai.

David LeBauer
la source
J'ai ajouté la balise MySQL en supposant que vos références à la documentation MySQL impliquaient que c'était la base de données que vous utilisez.
Justin Cave

Réponses:

10

Voici d'abord des exemples de données

mysql> drop table if exists mytable;
Query OK, 0 rows affected (0.03 sec)

mysql> create table mytable
    -> (
    ->     id int not null,
    ->     value VARCHAR(255),
    ->     primary key (id)
    -> );
Query OK, 0 rows affected (0.06 sec)

mysql> insert into mytable (id) values (1),(2),(3);
Query OK, 3 rows affected (0.06 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from mytable;
+----+-------+
| id | value |
+----+-------+
|  1 | NULL  |
|  2 | NULL  |
|  3 | NULL  |
+----+-------+
3 rows in set (0.00 sec)

mysql>

Voici la nouvelle requête

update mytable A inner join
(
    SELECT 1 id,'xyz' value UNION
    SELECT 2   ,'abc'       UNION
    SELECT 3   ,'def'

) B USING (id)
SET A.value = B.value;

Voici la nouvelle requête exécutée

mysql> update mytable A inner join
    -> (
    ->     SELECT 1 id,'xyz' value UNION
    ->     SELECT 2   ,'abc'       UNION
    ->     SELECT 3   ,'def'
    -> ) B USING (id)
    -> SET A.value = B.value;
Query OK, 0 rows affected (0.06 sec)
Rows matched: 3  Changed: 0  Warnings: 0

mysql> select * from mytable;
+----+-------+
| id | value |
+----+-------+
|  1 | xyz   |
|  2 | abc   |
|  3 | def   |
+----+-------+
3 rows in set (0.00 sec)

mysql>
RolandoMySQLDBA
la source
UPDATE table INNER JOIN ... USING(id) SET ...est génial
Nino Škopac
3

En supposant que vous ne souhaitez pas charger les données du fichier CSV dans une table de base de données, puis effectuer une corrélation UPDATE,

UPDATE mytable t
   SET value = (SELECT value
                  FROM tbl_with_csv_data csv
                 WHERE csv.primary_key = t.primary_key)
 WHERE EXISTS( SELECT 1
                 FROM tbl_with_csv_data csv
                 WHERE csv.primary_key = t.primary_key)

alors vous devriez pouvoir utiliser un CASE

UPDATE mytable t
   SET value = CASE WHEN primary_key = 1 THEN 'xyz'
                    WHEN primary_key = 2 THEN 'abc'
                    WHEN primary_key = 3 THEN 'def'
                    ELSE value
                END
 WHERE primary_key IN (1,2,3);
Justin Cave
la source