Ответ
Результат подзапроса SELECT можно использовать в UPDATE для определения обновляемых строк или вычисления новых значений. Это делается через подзапросы в условии WHERE или в выражении SET.
1. Подзапрос в условии WHERE (самый частый случай): Обновить записи на основе данных из другой таблицы.
-- Повысить зарплату сотрудникам IT-департамента
UPDATE employee e
SET e.salary = e.salary * 1.15
WHERE e.department_id IN (
SELECT d.id
FROM department d
WHERE d.name = 'IT'
);
-- Использование JOIN в UPDATE (более эффективно в некоторых СУБД)
UPDATE employee e
JOIN department d ON e.department_id = d.id
SET e.salary = e.salary * 1.15
WHERE d.name = 'IT';
2. Подзапрос в выражении SET: Установить значение на основе агрегации или выборки из другой таблицы.
-- Установить цену товара как среднюю цену по категории
UPDATE product p
SET p.price = (
SELECT AVG(price)
FROM product p2
WHERE p2.category_id = p.category_id
)
WHERE p.category_id = 5;
Важные замечания и best practices:
- Производительность: Подзапросы, особенно коррелированные (ссылающиеся на внешнюю таблицу), могут быть медленными на больших объемах данных. Всегда проверяйте
EXPLAINплан. - Читаемость: Для сложных условий часто лучше использовать
UPDATE ... FROM ... JOIN(синтаксис зависит от СУБД: PostgreSQL, MySQL 8.0+, SQL Server поддерживаютJOIN). - В JPA/Hibernate: Прямые DML-операции
UPDATEс подзапросами выполняются через нативные запросы (@QueryсnativeQuery = true) или критерии. HQL/JPQL поддерживает подзапросы вWHERE, но не вSETдля DML.@Repository public interface EmployeeRepository extends JpaRepository<Employee, Long> { @Modifying @Query(value = "UPDATE employee e SET e.salary = e.salary * 1.1 " + "WHERE e.department_id IN (SELECT d.id FROM department d WHERE d.name = :deptName)", nativeQuery = true) int giveRaiseToDepartment(@Param("deptName") String deptName); }