Czy zaktualizować wiele wierszy w tabeli za pomocą jednej instrukcji?

9

Jak najłatwiej zaktualizować wiele wierszy w tabeli? Mam plik csv, który wygląda następująco:

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

Wiersze z tymi kluczami podstawowymi już istnieją w tabeli docelowej

Chciałbym zaktualizować tabelę docelową o te wartości. Czy istnieje składnia, dzięki której mogę napisać coś takiego:

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

Przeglądając MySQL Update Reference , tę stronę ( MySQL - aktualizacja csv ), SO ( aktualizuj wiele wierszy , wiele aktualizacji db , aktualizuj wiele wierszy ), podejrzewam, że odpowiedź brzmi „nie”, ale chciałbym potwierdzić, że to jest prawdziwy.

David LeBauer
źródło
Dodałem tag MySQL, zakładając, że twoje odniesienia do dokumentacji MySQL sugerują, że korzystasz z bazy danych.
Justin Cave

Odpowiedzi:

10

Najpierw są przykładowe dane

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>

Oto nowe zapytanie

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;

Oto nowe zapytanie wykonane

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
źródło
UPDATE table INNER JOIN ... USING(id) SET ...jest świetne
Nino Škopac
3

Zakładając, że nie chcesz ładować danych z pliku CSV do tabeli bazy danych, a następnie wykonać korelację 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)

wtedy powinieneś być w stanie użyć 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
źródło