UPDATE в SQL: не путай с «обновлением Windows»

UPDATE — это команда, с помощью которой мы меняем данные, уже существующие в таблице.Не добавляем новые строки (как INSERT), не удаляем (как DELETE), а правим то, что есть.

А пока подписывайся на мой канал На связи: SQL Там я публикую посты про особенности и нюансы SQL. Этот канал про то, как не бояться баз данных, понимать, что такое JOIN, GROUP BY и почему NULL ≠ 0. Его я веду с нуля подписчиков. Присоединяйся!

Базовый синтаксис выглядит следующим образом:

UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;
  • UPDATE table_name → в какой таблице меняем данные.
  • SET → что именно меняем и на какие значения.
  • WHERE → условие, чтобы обновить только нужные строки.

Если забыть WHERE → обновятся все строки таблицы. Классический факап новичка.

Где и когда используется?

  • Меняем телефон у клиента → UPDATE customers SET phone = '...' WHERE id = 5;
  • Уменьшаем остаток товара после покупки.
  • Обновляем статус заказа.

Проще говоря: везде, где данные живые и меняются со временем.

Можно обновлять сразу несколько строк:

UPDATE products SET price = price * 0.9 WHERE category = 'clothes';

В этом запросе нет ограничений по количеству строк, если в таблице есть 10 строк с категорией = 'clothes', то скидка в 10% применится ко всем 10 строкам.

В UPDATE можно использовать JOIN при более сложной логике

UPDATE orders o SET amount = amount * 1.1 FROM customers c WHERE o.customer_id = c.id AND c.vip = true;

Мы делаем обновления в таблице orders, но делаем их для тех покупателей, у которых есть признак ВИП. А признак ВИП хранится в таблице customers.

В этом запросе явно не указан JOIN, но с JOIN запрос выглядел бы вот так:

UPDATE orders o SET amount = amount * 1.1 FROM orders o2 JOIN customers c ON o2.customer_id = c.id WHERE o.id = o2.id AND c.vip = true;

Здесь больше строк, поэтому многие предпочитают первый вариант.

  • PostgreSQL, SQL Server → поддерживают UPDATE ... FROM.
  • MySQL → там другой синтаксис:
UPDATE orders o JOIN customers c ON o.customer_id = c.id SET o.amount = o.amount * 1.1 WHERE c.vip = true;

Т.е. в MySQL JOIN присутствует в явном виде.

RETURNING в PostgreSQL

UPDATE orders SET status = 'done' WHERE id = 101 RETURNING *;

Сразу получаешь обновлённые строки, без лишнего SELECT. В MySQL и SQL Server такого нет.

Deadlock при UPDATE

  • Транзакция А захватила строку 1 и ждёт строку 2.
  • Транзакция B захватила строку 2 и ждёт строку 1.
  • Обе ждут друг друга бесконечно.

База видит: «ну, так не пойдёт» → и убивает одну из транзакций, чтобы освободить дорогу.

  • При обычной блокировке ты просто ждёшь, пока другой закончит.
  • При deadlock оба ждут друг друга, и никто никогда не закончит — тупик.

В UPDATE можно использовать подзапросы:

UPDATE employees SET salary = salary + 5000 WHERE department_id = ( SELECT id FROM departments WHERE name = 'IT' );

Здесь UPDATE зависит от результата подзапроса.

UPDATE без SET

В некоторых СУБД (например, SQL Server) можно писать:

UPDATE table_name SET column = column;

На вид — бесполезно. Но так можно снимать блокировки или триггерить AFTER UPDATE.

Можно использовать TOP и LIMIT при UPDATE

UPDATE TOP (10) users SET active = 0; -- для SQL Server
UPDATE users SET active = 0 LIMIT 10; -- для MySQL

А вот для PostgreSQL такого механизма нет - надо будет через CTE реализовывать.

UPDATE — мощный инструмент. Он нужен везде, где данные живут и меняются. Но:

  • всегда помни про WHERE,
  • учитывай блокировки,
  • и знай фишки СУБД (RETURNING, JOIN, LIMIT).

Напоминаю про свой канал На связи: SQL Присоединяйся для обсуждения вопросов по изучению SQL.

Начать дискуссию