Как выполнить 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?
"Вставка результатов хранимой процедуры в временную таблицу"
Как экранировать одинарную кавычку в SQL Server?
Обновление данных в одной таблице из другой на основе совпадения ID
Следует ли мне использовать != или <> для обозначения "не равно" в T-SQL?