Ответ
Результат подзапроса 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); }
Ответ 18+ 🔞
Да ты посмотри, какая, блядь, интересная штука! Результат этого самого SELECT можно, сука, впихнуть прямо в UPDATE, чтобы понять, какие строки трогать или новые значения посчитать. Вообще, это через подзапросы в WHERE или в самом SET делается.
1. Подзапрос в WHERE (самое, блядь, частое применение):
Тут мы обновляем записи, отталкиваясь от данных из другой таблицы. Представь, как начальник отделу IT зарплату поднимает.
-- Повысить зарплату сотрудникам 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;
А теперь, блядь, важные моменты, чтобы не наебнуться:
- Скорость: Подзапросы, особенно те, что на внешнюю таблицу ссылаются (коррелированные), могут на больших данных тормозить, как черепаха в сиропе. Всегда смотри
EXPLAIN, не ленись, епта. - Понятность: Если условия сложные — проще часто через
UPDATE ... FROM ... JOINсделать. Но синтаксис, блядь, разный у PostgreSQL, MySQL и прочих. - В JPA/Hibernate: Прямые такие
UPDATEс подзапросами — это удел нативных запросов (@QueryсnativeQuery = true) или критериев. HQL/JPQL подзапросы вWHEREдля DML ещё куда ни шло, а вот вSET— нихуя.@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); }
Вот так вот, блядь. Главное — головой думай, а не просто копипасть.