¿Actualizar muchas filas en una tabla con una sola declaración?
Pregunta
¿Cuál es la forma más fácil de actualizar muchas filas en una mesa? Tengo un archivo CSV que se ve así:
|primary_key |value|
| 1 | xyz|
| 2 | abc|
| 3 | def|
...
Las filas con estas claves primarias ya existen en la tabla de destino
Me gustaría actualizar la tabla de destino con estos valores. ¿Hay sintaxis para que pueda escribir algo como:
update mytable set value = ('xyz', 'abc', 'def') where primary key = (1,2,3);
Mirando a través del Referencia de actualización de MySQL, este sitio (MySQL - Actualización de CSV), ASI QUE (Actualizar múltiples filas, múltiples actualizaciones de DB, Actualizar múltiples filas), Sospecho que la respuesta es "no", pero me gustaría confirmar que esto es cierto.
Solución
Primero aquí están los datos de muestra
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>
Aquí está la nueva consulta
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;
Aquí está la nueva consulta ejecutada
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>
Otros consejos
Suponiendo que no desea cargar los datos del archivo CSV en una tabla de base de datos y luego hacer un correlacionado 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)
Entonces deberías poder usar 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);