SQL - обновление нескольких записей в одном запросе

133

У меня есть таблица - config . Схема: config_name | config_value

И я хотел бы обновить несколько записей одним запросом. Я так стараюсь:

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

но этот запрос неверен :(

Вы можете помочь мне?

user3022527
источник
1
Какую базу данных вы используете?
Hart CO
Я использую базу данных MySQL.
user3022527
Обновление от Select может быть ответом stackoverflow.com/questions/2334712/…
Джонатан Бенн,

Ответы:

170

Попробуйте либо синтаксис обновления нескольких таблиц

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';

Вот демонстрация SQLFiddle

или условное обновление

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');

Вот демонстрация SQLFiddle

peterm
источник
1
Да, это нормально, но что, если мне захочется обновить 16 записей за один запрос? Мне шолудь использовать JOIN x 16?
user3022527
20
Вы должны в первую очередь упомянуть такие важные детали в своем вопросе. В любом случае см. Обновленный ответ для другого решения (условное обновление).
peterm
1
Что такое t1 и t2 в ваших примерах?
Paul Brewczynski
1
И тебе привет, @PaulBrewczynski. Это псевдонимы таблиц, и их можно писать, config AS t1где ASэто необязательно.
peterm 07
@peterm: ссылки SQLFiddle не работают. В остальном техника условного обновления работает отлично. Спасибо!
Джонатан Бенн
142

Вы можете сделать это с помощью INSERT, как показано ниже:

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);

Это вставляет новые значения в таблицу, но если первичный ключ дублируется (уже вставлен в таблицу), указанные вами значения будут обновлены, и та же запись не будет вставлена ​​второй раз.

Камилла Халаги
источник
26
довольно умный хак. Я удивлен.
Blaise
6
Не поддерживается для Postgres см: stackoverflow.com/questions/1109061/...
kevzettler
Кроме того, это отличный способ превратить немного CSV (или много) в таблицу Insert / Update / Upsert с небольшим редактированием текста!
wulftone
6
Это решение MySQL, а не Postgres или MSSQL.
Rz Mk
1
Это увеличит идентификатор автоинкремента, даже если запись не вставлена ​​или не обновлена
Тимо Хуовинен
15

в моем случае мне нужно обновить записи, которые больше 1000, для этого вместо того, чтобы нажимать запрос обновления каждый раз, когда я предпочел это,

   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 - это идентификаторы пользователей, и для этих идентификаторов мне нужно обновить base_id 999 и 88 соответственно. Это работает для меня.

Вайбхав Кулкарни
источник
Один из лучших здесь, отлично поработал для меня.
Шахрукх Анвар
7

может кому то будет полезно

для Postgresql 9.5 работает как прелесть

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

этот SQL обновляет существующую запись и вставляет новую (2 в 1)

Олег Собчук
источник
1
Как я вижу, id - это pk для таблицы согласно вашему запросу. Предположим, что есть 2 или более столбца, рассматриваемых как pk (составной ключ) ... В этом случае, каков должен быть правильный способ проверки конфликта.
Шритам Джагадев
6

Решение Камиллы сработало. Превратил его в базовую функцию PHP, которая записывает оператор SQL. Надеюсь, это поможет кому-то другому.

    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
источник
5

вместо этого

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';

ты можешь использовать

UPDATE staff SET salary = 1200 WHERE name IN ('Bob', 'Frank', 'John');
Шухад заман
источник
3

Выполните приведенный ниже код, чтобы обновить количество строк, где Parent ID - это идентификатор, из которого вы хотите получить данные, а Child ids - это идентификаторы, которые вам нужно обновить, поэтому вам просто нужно добавить родительский идентификатор и дочерние идентификаторы для обновления все строки вам нужны, используя небольшой скрипт.

    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])
Харриш Сельвараджа
источник
2

Предполагая, что у вас есть список значений для обновления в электронной таблице Excel с config_value в столбце A1 и config_name в B1, вы можете легко написать там запрос, используя формулу Excel, например

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

Ивар
источник
1

Выполните приведенный ниже код, если вы хотите обновить всю запись во всех столбцах:

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

и если вы хотите обновить все столбцы определенной строки, выполните следующий код:

update config set column1='value',column2='value'...columnN='value' where column1='value'
Джейсон Кларк
источник
3
а что, если разные значения в разных строках? например, ОБНОВЛЕНИЕ УСТАНОВИТЬ зарплату сотрудников = 1125 ГДЕ name = 'Bob'; ОБНОВЛЕНИЕ сотрудников УСТАНОВИТЬ зарплату = 1200 ГДЕ name = 'Jane'; ОБНОВЛЕНИЕ сотрудников УСТАНОВИТЬ зарплату = 1100 ГДЕ name = 'Frank'; ОБНОВЛЕНИЕ сотрудников УСТАНОВИТЬ зарплату = 1175 ГДЕ name = 'Susan'; ОБНОВИТЬ персонал УСТАНОВИТЬ зарплату = 1150 ГДЕ name = 'John';
Абдулла Нурум