SQL - zaktualizuj wiele rekordów w jednym zapytaniu

136

Mam tabelę - config . Schemat: config_name | config_value

Chciałbym zaktualizować wiele rekordów w jednym zapytaniu. Próbuję tak:

UPDATE config 
SET t1.config_value = 'value'
  , t2.config_value = 'value2' 
WHERE t1.config_name = 'name1' 
  AND t2.config_name = 'name2';

ale to zapytanie jest błędne :(

Możesz mi pomóc?

user3022527
źródło
1
Z jakiej bazy danych korzystasz?
Hart CO
Używam bazy danych MySQL.
user3022527
Aktualizacja z Select może być odpowiedzią stackoverflow.com/questions/2334712/ ...
Jonathan Benn

Odpowiedzi:

179

Wypróbuj dowolną składnię aktualizacji dla wielu tabel

UPDATE config t1 JOIN config t2
    ON t1.config_name = 'name1' AND t2.config_name = 'name2'
   SET t1.config_value = 'value',
       t2.config_value = 'value2';

Oto demo SQLFiddle

lub warunkowa aktualizacja

UPDATE config
   SET config_value = CASE config_name 
                      WHEN 'name1' THEN 'value' 
                      WHEN 'name2' THEN 'value2' 
                      ELSE config_value
                      END
 WHERE config_name IN('name1', 'name2');

Oto demo SQLFiddle

peterm
źródło
2
Tak, w porządku, ale co, kiedy wolę zaktualizować 16 rekordów w jednym zapytaniu? Powinienem użyć JOIN x 16?
user3022527
21
Państwo powinno wymienić takie ważne szczegóły w swoim pytaniu w pierwszej kolejności. W każdym razie zobacz zaktualizowaną odpowiedź na inne rozwiązanie (aktualizacja warunkowa).
peterm
1
Co to jest t1 i t2 w twoich przykładach?
Paul Brewczyński
1
Tobie też witam @PaulBrewczynski. Są to aliasy tabel i można je zapisać, config AS t1gdzie ASjest opcjonalne.
peterm
@peterm: łącza SQLFiddle są zepsute. W przeciwnym razie technika warunkowej aktualizacji działa świetnie. Dzięki!
Jonathan Benn
148

Możesz to zrobić za pomocą INSERT jak poniżej:

INSERT INTO mytable (id, a, b, c)
VALUES (1, 'a1', 'b1', 'c1'),
(2, 'a2', 'b2', 'c2'),
(3, 'a3', 'b3', 'c3'),
(4, 'a4', 'b4', 'c4'),
(5, 'a5', 'b5', 'c5'),
(6, 'a6', 'b6', 'c6')
ON DUPLICATE KEY UPDATE id=VALUES(id),
a=VALUES(a),
b=VALUES(b),
c=VALUES(c);

Spowoduje to wstawienie nowych wartości do tabeli, ale jeśli klucz podstawowy zostanie zduplikowany (już wstawiony do tabeli), określone wartości zostaną zaktualizowane, a ten sam rekord nie zostanie wstawiony po raz drugi.

Camille Khalaghi
źródło
28
całkiem sprytny hack. Jestem zdumiony.
Blaise,
6
Nieobsługiwane dla Postgres patrz: stackoverflow.com/questions/1109061/…
kevzettler
Ponadto jest to świetny sposób, aby zamienić trochę CSV (lub dużo) w wstawianie / aktualizowanie / ulepszanie tabeli z niewielką edycją tekstu!
wulftone,
6
To jest rozwiązanie MySQL, a nie Postgres czy MSSQL.
Rz Mk
1
Spowoduje to zwiększenie identyfikatora autoincrement, nawet jeśli rekord nie jest wstawiony ani zaktualizowany
Timo Huovinen
15

w moim przypadku muszę zaktualizować rekordy, których jest więcej niż 1000, w tym celu zamiast uderzać w zapytanie aktualizujące za każdym razem, gdy wolę to,

   UPDATE mst_users 
   SET base_id = CASE user_id 
   WHEN 78 THEN 999 
   WHEN 77 THEN 88 
   ELSE base_id END WHERE user_id IN(78, 77)

78,77 to identyfikatory użytkowników i dla tych identyfikatorów muszę zaktualizować odpowiednio base_id 999 i 88. To działa dla mnie.

vaibhav kulkarni
źródło
Jeden z najlepszych tutaj, działał świetnie dla mnie.
Shahrukh Anwar
7

może komuś się przyda

dla Postgresql 9.5 działa jak urok

INSERT INTO tabelname(id, col2, col3, col4)
VALUES
    (1, 1, 1, 'text for col4'),
    (DEFAULT,1,4,'another text for col4')
ON CONFLICT (id) DO UPDATE SET
    col2 = EXCLUDED.col2,
    col3 = EXCLUDED.col3,
    col4 = EXCLUDED.col4

ten SQL aktualizuje istniejący rekord i wstawia nowy rekord (2 w 1)

Oleg Sobchuk
źródło
1
Jak widzę, id to pk dla tabeli zgodnie z zapytaniem. Załóżmy, że istnieją 2 lub więcej kolumn uznanych za pk (klucz złożony) ... W takim przypadku, jaki powinien być prawidłowy sposób sprawdzenia konfliktu.
Sritam Jagadev,
6

Rozwiązanie Camille zadziałało. Przekształcił go w podstawową funkcję PHP, która zapisuje instrukcję SQL. Mam nadzieję, że to pomoże komuś innemu.

    function _bulk_sql_update_query($table, $array)
    {
        /*
         * Example:
        INSERT INTO mytable (id, a, b, c)
        VALUES (1, 'a1', 'b1', 'c1'),
        (2, 'a2', 'b2', 'c2'),
        (3, 'a3', 'b3', 'c3'),
        (4, 'a4', 'b4', 'c4'),
        (5, 'a5', 'b5', 'c5'),
        (6, 'a6', 'b6', 'c6')
        ON DUPLICATE KEY UPDATE id=VALUES(id),
        a=VALUES(a),
        b=VALUES(b),
        c=VALUES(c);
    */
        $sql = "";

        $columns = array_keys($array[0]);
        $columns_as_string = implode(', ', $columns);

        $sql .= "
      INSERT INTO $table
      (" . $columns_as_string . ")
      VALUES ";

        $len = count($array);
        foreach ($array as $index => $values) {
            $sql .= '("';
            $sql .= implode('", "', $array[$index]) . "\"";
            $sql .= ')';
            $sql .= ($index == $len - 1) ? "" : ", \n";
        }

        $sql .= "\nON DUPLICATE KEY UPDATE \n";

        $len = count($columns);
        foreach ($columns as $index => $column) {

            $sql .= "$column=VALUES($column)";
            $sql .= ($index == $len - 1) ? "" : ", \n";
        }

        $sql .= ";";

        return $sql;
    }
adamk
źródło
5

zamiast tego

UPDATE staff SET salary = 1200 WHERE name = 'Bob';
UPDATE staff SET salary = 1200 WHERE name = 'Jane';
UPDATE staff SET salary = 1200 WHERE name = 'Frank';
UPDATE staff SET salary = 1200 WHERE name = 'Susan';
UPDATE staff SET salary = 1200 WHERE name = 'John';

możesz użyć

UPDATE staff SET salary = 1200 WHERE name IN ('Bob', 'Frank', 'John');
Shuhad zaman
źródło
3

Wykonaj poniższy kod, aby zaktualizować n liczbę wierszy, gdzie Parent ID to identyfikator, z którego chcesz pobrać dane, a Child ID to identyfikatory, które musisz zaktualizować, więc wystarczy dodać identyfikator rodzica i identyfikatory dziecka do aktualizacji wszystkie wiersze, których potrzebujesz, używając małego skryptu.

    UPDATE [Table]
 SET couloumn1= (select couloumn1 FROM Table WHERE IDCouloumn = [PArent ID]),
     couloumn2= (select couloumn2 FROM Table WHERE IDCouloumn = [PArent ID]),
     couloumn3= (select couloumn3 FROM Table WHERE IDCouloumn = [PArent ID]),
     couloumn4= (select couloumn4 FROM Table WHERE IDCouloumn = [PArent ID]),
 WHERE IDCouloumn IN ([List of child Ids])
Harrish Selvarajah
źródło
2

Zakładając, że masz listę wartości do zaktualizowania w arkuszu kalkulacyjnym Excel z wartością_konfiguracji w kolumnie A1 i nazwa_konfiguracji w B1 , możesz łatwo zapisać tam zapytanie za pomocą formuły programu Excel, takiej jak

=CONCAT("UPDATE config SET config_value = ","'",A1,"'", " WHERE config_name = ","'",B1,"'")

Ivar
źródło
1

Wykonaj poniższy kod, jeśli chcesz zaktualizować cały rekord we wszystkich kolumnach:

update config set column1='value',column2='value'...columnN='value';

a jeśli chcesz zaktualizować wszystkie kolumny w danym wierszu, wykonaj poniższy kod:

update config set column1='value',column2='value'...columnN='value' where column1='value'
Jason Clark
źródło
3
co jeśli inna wartość w innym wierszu? na przykład UPDATE staff SET pensja = 1125 WHERE name = 'Bob'; UPDATE wynagrodzenie SET pracowników = 1200 WHERE name = 'Jane'; AKTUALIZUJ wynagrodzenie pracowników SET = 1100 WHERE name = 'Frank'; UPDATE wynagrodzenie pracowników SET = 1175 WHERE name = 'Susan'; UPDATE wynagrodzenie pracowników SET = 1150 WHERE name = 'John';
Abdullah Nurum