Как выполнить UPDATE с использованием SELECT в SQL Server?
В SQL Server можно вставлять строки в таблицу с помощью оператора INSERT.. SELECT. Пример:
INSERT INTO Table (col1, col2, col3)
SELECT col1, col2, col3
FROM other_table
WHERE sql = 'cool'
Но есть ли возможность обновить таблицу с помощью SELECT? У меня есть временная таблица, содержащая необходимые значения, и я хотел бы обновить другую таблицу, используя эти значения. Может быть, что-то вроде этого:
UPDATE Table SET col1, col2
SELECT col1, col2
FROM other_table
WHERE sql = 'cool'
WHERE Table.id = other_table.id
Как правильно сформулировать запрос для обновления таблицы с использованием значений из другой таблицы?
4 ответ(ов)
Ваш запрос обновляет данные в таблице Table_A, используя значения из Table_B, при этом происходит слияние таблиц по идентификатору id. Обновляются поля col1 и col2 в Table_A, если условие в WHERE выполняется, т.е. когда значение col3 равно 'cool'.
Вот более понятное объяснение по шагам:
- UPDATE - мы выбираем таблицу для обновления:
Table_A. - SET - здесь задаются новые значения для обновляемых столбцов:
Table_A.col1получает значение изTable_B.col1.Table_A.col2получает значение изTable_B.col2.
- FROM - указываем, какие таблицы будем использовать. Здесь мы делаем
INNER JOINмеждуTable_AиTable_Bпо условию равенстваid. - WHERE - фильтруем строки, чтобы обновление прошло только для тех записей, где
Table_A.col3равно 'cool'.
Итак, данная команда обновляет все записи в Table_A, которые соответствуют указанному условию и имеют общие идентификаторы с Table_B, устанавливая новые значения для col1 и col2.
Один из способов обновить данные в таблице, основываясь на значениях из другой таблицы, можно реализовать следующим образом:
UPDATE t
SET t.col1 = o.col1,
t.col2 = o.col2
FROM
other_table o
JOIN
t ON t.id = o.id
WHERE
o.sql = 'cool'
В этом запросе мы обновляем столбцы col1 и col2 в таблице t, используя значения из таблицы other_table, где условие o.sql = 'cool'. Обратите внимание, что мы связываем таблицы по идентификатору id, чтобы обеспечить корректное обновление только необходимых записей.
Ещё одна возможность, которая не была упомянута ранее, — это просто вложить сам оператор SELECT в CTE, а затем обновить этот CTE.
WITH CTE AS (
SELECT T1.Col1,
T2.Col1 AS _Col1,
T1.Col2,
T2.Col2 AS _Col2
FROM T1
JOIN T2 ON T1.id = T2.id
/* Условие WHERE добавлено для исключения строк, которые совпадают в обеих таблицах
Корректно обрабатывает NULL значения */
WHERE EXISTS (
SELECT T1.Col1, T1.Col2
EXCEPT
SELECT T2.Col1, T2.Col2
)
)
UPDATE CTE
SET Col1 = _Col1,
Col2 = _Col2;
Это имеет преимущество в том, что вы можете сначала запустить оператор SELECT отдельно, чтобы проверить результаты, но вам потребуется присвоить алиасы столбцам, как показано выше, если они имеют одинаковые имена в исходных и целевых таблицах.
Однако у этого подхода есть то же ограничение, что и у проприетарного синтаксиса UPDATE ... FROM, описанного в четырех других ответах. Если исходная таблица находится на стороне "многие" в соединении "один-ко-многим", то невозможно предсказать, какая из возможных совпадающих записей будет использована в операторе UPDATE (проблема, которую MERGE устраняет, вырабатывая ошибку, если пытаются обновить одну и ту же строку несколько раз).
Для справки (и для других, кто искал так же, как и я), вы можете сделать это в MySQL следующим образом:
UPDATE first_table, second_table
SET first_table.color = second_table.color
WHERE first_table.id = second_table.foreign_id;
Как выполнить оператор UPDATE с JOIN в SQL Server?
Запрос UPDATE в SQL с использованием JOINов
"Вставка результатов хранимой процедуры в временную таблицу"
Обновление данных в одной таблице из другой на основе совпадения ID
Возможно ли задать условия в Count()?