提问人:jamesmhaley 提问时间:2/25/2010 最后编辑:Jatin Morarjamesmhaley 更新时间:9/29/2023 访问量:5235237
如何从 SQL Server 中的 SELECT 进行 UPDATE 操作?
How do I UPDATE from a SELECT in 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
答:
UPDATE
Table_A
SET
Table_A.col1 = Table_B.col1,
Table_A.col2 = Table_B.col2
FROM
Some_Table AS Table_A
INNER JOIN Other_Table AS Table_B
ON Table_A.id = Table_B.id
WHERE
Table_A.col3 = 'cool'
评论
SET Table.other_table_id = @NewValue
ON Table.id = @IdToEdit AND other_table.id = @NewValue
UPDATE Table_A, Table_B SET Table_A.col1 = Table_B.col1 WHERE Table_A.id = Table_B.table_a_id
单程
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'
评论
t.id
JOIN t
UPDATE t
t
我会将 Robin 的出色回答修改为以下内容:
UPDATE Table
SET Table.col1 = other_table.col1,
Table.col2 = other_table.col2
FROM
Table
INNER JOIN other_table ON Table.id = other_table.id
WHERE
Table.col1 != other_table.col1
OR Table.col2 != other_table.col2
OR (
other_table.col1 IS NOT NULL
AND Table.col1 IS NULL
)
OR (
other_table.col2 IS NOT NULL
AND Table.col2 IS NULL
)
如果没有 WHERE 子句,您甚至会影响不需要受影响的行,这(可能)会导致索引重新计算或触发实际上不应该触发的触发器。
评论
WHERE EXISTS(SELECT T1.Col1, T1.Col2 EXCEPT SELECT T2.Col1, T2.Col2))
更简洁。
我添加它只是为了让您看到一种快速编写它的方法,以便您可以在进行更新之前检查将要更新的内容。
UPDATE Table
SET Table.col1 = other_table.col1,
Table.col2 = other_table.col2
--select Table.col1, other_table.col,Table.col2,other_table.col2, *
FROM Table
INNER JOIN other_table
ON Table.id = other_table.id
在 SQL Server 2008(或更高版本)中,使用 MERGE
MERGE INTO YourTable T
USING other_table S
ON T.id = S.id
AND S.tsql = 'cool'
WHEN MATCHED THEN
UPDATE
SET col1 = S.col1,
col2 = S.col2;
或者:
MERGE INTO YourTable T
USING (
SELECT id, col1, col2
FROM other_table
WHERE tsql = 'cool'
) S
ON T.id = S.id
WHEN MATCHED THEN
UPDATE
SET col1 = S.col1,
col2 = S.col2;
评论
MERGE
也可用于“更新插入”记录;也就是说,如果存在匹配记录,则在未找到匹配项时创建新记录UPDATE
INSERT
UPDATE
MERGE
UPDATE
另一种尚未提及的可能性是将语句本身放入 CTE 中,然后更新 CTE。SELECT
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 clause added to exclude rows that are the same in both tables
Handles NULL values correctly*/
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
评论
CTE
;WITH SomeCompexCTE AS (...), CTEAsAbove AS (SELECT T1.Col1,... FROM T1 JOIN SomeComplexCTE...) UPDATE CTEAsAbove SET Col1=_Col1, ...
UPDATE YourTable
SET Col1 = OtherTable.Col1,
Col2 = OtherTable.Col2
FROM (
SELECT ID, Col1, Col2
FROM other_table) AS OtherTable
WHERE
OtherTable.ID = YourTable.ID
评论
SET Table_A.col1 = SUM(Table_B.col1)
INSERT ... SELECT
使用别名:
UPDATE t
SET t.col1 = o.col1
FROM table1 AS t
INNER JOIN
table2 AS o
ON t.id = o.id
这可能是执行更新的利基原因(例如,主要用于过程),或者对其他人来说可能是显而易见的,但还应该说明,您可以在不使用 join 的情况下执行 update-select 语句(以防您更新的表没有公共字段)。
update
Table
set
Table.example = a.value
from
TableExample a
where
Table.field = *key value* -- finds the row in Table
AND a.field = *key value* -- finds the row in TableExample a
评论
作为记录(以及其他像我一样搜索的人),您可以在MySQL中像这样进行操作:
UPDATE first_table, second_table
SET first_table.color = second_table.color
WHERE first_table.id = second_table.foreign_id
简单的方法是:
UPDATE
table_to_update,
table_info
SET
table_to_update.col1 = table_info.col1,
table_to_update.col2 = table_info.col2
WHERE
table_to_update.ID = table_info.ID
评论
下面是另一个有用的语法:
UPDATE suppliers
SET supplier_name = (SELECT customers.name
FROM customers
WHERE customers.customer_id = suppliers.supplier_id)
WHERE EXISTS (SELECT customers.name
FROM customers
WHERE customers.customer_id = suppliers.supplier_id);
它使用“WHERE EXIST”检查它是否为 null。
评论
SELECT value FROM table_1 INNER JOIN ( SELECT * FROM table_2 WHERE ..... ) ON ( ...... )
以下示例使用派生表(FROM 子句后面的 SELECT 语句)返回旧值和新值以进行进一步更新:
UPDATE x
SET x.col1 = x.newCol1,
x.col2 = x.newCol2
FROM (SELECT t.col1,
t2.col1 AS newCol1,
t.col2,
t2.col2 AS newCol2
FROM [table] t
JOIN other_table t2
ON t.ID = t2.ID) x
如果使用 MySQL 而不是 SQL Server,则语法为:
UPDATE Table1
INNER JOIN Table2
ON Table1.id = Table2.id
SET Table1.col1 = Table2.col1,
Table1.col2 = Table2.col2
评论
Table2.col1
用:
drop table uno
drop table dos
create table uno
(
uid int,
col1 char(1),
col2 char(2)
)
create table dos
(
did int,
col1 char(1),
col2 char(2),
[sql] char(4)
)
insert into uno(uid) values (1)
insert into uno(uid) values (2)
insert into dos values (1,'a','b',null)
insert into dos values (2,'c','d','cool')
select * from uno
select * from dos
也:
update uno set col1 = (select col1 from dos where uid = did and [sql]='cool'),
col2 = (select col2 from dos where uid = did and [sql]='cool')
或:
update uno set col1=d.col1,col2=d.col2 from uno
inner join dos d on uid=did where [sql]='cool'
select * from uno
select * from dos
如果两个表中的 ID 列名相同,则只需将表名放在要更新的表之前,并为所选表使用别名,即:
update uno set col1 = (select col1 from dos d where uno.[id] = d.[id] and [sql]='cool'),
col2 = (select col2 from dos d where uno.[id] = d.[id] and [sql]='cool')
如果你想把表与它自己连接起来(这不会经常发生):
update t1 -- just reference table alias here
set t1.somevalue = t2.somevalue
from table1 t1 -- these rows will be the targets
inner join table1 t2 -- these rows will be used as source
on .................. -- the join clause is whatever suits you
评论
targett1
sourcet1
以下解决方案适用于MySQL数据库:
UPDATE table1 a , table2 b
SET a.columname = 'some value'
WHERE b.columnname IS NULL ;
UPDATE table AS a
INNER JOIN table2 AS b
ON a.col1 = b.col1
INNER JOIN ... AS ...
ON ... = ...
SET ...
WHERE ...
在 SQL 数据库中使用 INNER JOIN 从 SELECT 执行 UPDATE
由于这篇文章的回复太多了,投票最多,我想我也会在这里提供我的建议。虽然这个问题很有趣,但我在许多论坛网站上看到过,并使用带有屏幕截图的 INNER JOIN 做出了解决方案。
首先,我创建了一个名为 schoolold 的表,并插入了有关其列名的几条记录并执行它。
然后我执行SELECT命令来查看插入的记录。
然后,我创建了一个名为 schoolnew 的新表,并对其执行了类似的上述操作。
然后,要查看其中插入的记录,我执行SELECT命令。
现在,我想在第三行和第四行进行一些更改,以完成此操作,我使用INNER JOIN执行UPDATE命令。
为了查看更改,我执行了 SELECT 命令。
您可以看到,通过使用带有 UPDATE 语句的 INNER JOIN,如何轻松地将表 schoolold 的第三和第四条记录替换为表 schoolnew。
更新比这里的其他答案更具可读性:CTE
;WITH cte
AS (SELECT col1,col2,id
FROM other_table
WHERE sql = 'cool')
UPDATE A
SET A.col1 = B.col1,
A.col2 = B.col2
FROM table A
INNER JOIN cte B
ON A.id = B.id
另一种方法是使用派生表:
UPDATE t
SET t.col1 = a.col1
,t.col2 = a.col2
FROM (
SELECT id, col1, col2 FROM @tbl2) a
INNER JOIN @tbl1 t ON t.id = a.id
示例数据
DECLARE @tbl1 TABLE (id INT, col1 VARCHAR(10), col2 VARCHAR(10))
DECLARE @tbl2 TABLE (id INT, col1 VARCHAR(10), col2 VARCHAR(10))
INSERT @tbl1 SELECT 1, 'a', 'b' UNION SELECT 2, 'b', 'c'
INSERT @tbl2 SELECT 1, '1', '2' UNION SELECT 2, '3', '4'
UPDATE t
SET t.col1 = a.col1
,t.col2 = a.col2
FROM (
SELECT id, col1, col2 FROM @tbl2) a
INNER JOIN @tbl1 t ON t.id = a.id
SELECT * FROM @tbl1
SELECT * FROM @tbl2
从 select 语句更新的另一种方法:
UPDATE A
SET A.col = A.col,B.col1 = B.col1
FROM first_Table AS A
INNER JOIN second_Table AS B ON A.id = B.id WHERE A.col2 = 'cool'
评论
UPDATE TQ
SET TQ.IsProcessed = 1, TQ.TextName = 'bla bla bla'
FROM TableQueue TQ
INNER JOIN TableComment TC ON TC.ID = TQ.TCID
WHERE TQ.IsProcessed = 0
若要确保更新所需的内容,请选择“首先”
SELECT TQ.IsProcessed, 1 AS NewValue1, TQ.TextName, 'bla bla bla' AS NewValue2
FROM TableQueue TQ
INNER JOIN TableComment TC ON TC.ID = TQ.TCID
WHERE TQ.IsProcessed = 0
甚至还有一种更短的方法,您可能会感到惊讶:
示例数据集:
CREATE TABLE #SOURCE ([ID] INT, [Desc] VARCHAR(10));
CREATE TABLE #DEST ([ID] INT, [Desc] VARCHAR(10));
INSERT INTO #SOURCE VALUES(1,'Desc_1'), (2, 'Desc_2'), (3, 'Desc_3');
INSERT INTO #DEST VALUES(1,'Desc_4'), (2, 'Desc_5'), (3, 'Desc_6');
法典:
UPDATE #DEST
SET #DEST.[Desc] = #SOURCE.[Desc]
FROM #SOURCE
WHERE #DEST.[ID] = #SOURCE.[ID];
评论
如果您使用的是 SQL Server,则可以在不指定联接的情况下从一个表更新另一个表,只需从子句中链接这两个表即可。这使得 SQL 查询变得更加简单:where
UPDATE Table1
SET Table1.col1 = Table2.col1,
Table1.col2 = Table2.col2
FROM
Table2
WHERE
Table1.id = Table2.id
在被接受的答案中,在:
SET
Table_A.col1 = Table_B.col1,
Table_A.col2 = Table_B.col2
我想补充一点:
OUTPUT deleted.*, inserted.*
我通常做的是将所有内容放入一个回滚支持的事务中,并使用 : 这样我就能看到即将发生的一切。当我对我所看到的感到满意时,我会将 ."OUTPUT"
ROLLBACK
COMMIT
我通常需要记录我所做的事情,所以我在运行回滚查询时使用该选项,并保存脚本和 OUTPUT 的结果。(当然,如果我更改了太多行,这是不切实际的)"results to Text"
在这里整合所有不同的方法。
- 选择更新
- 使用公用表表达式进行更新
- 合并
示例表结构如下,将从 Product_BAK 更新为 Product 表。
表产品
CREATE TABLE [dbo].[Product](
[Id] [int] IDENTITY(1, 1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[Description] [nvarchar](100) NULL
) ON [PRIMARY]
表Product_BAK
CREATE TABLE [dbo].[Product_BAK](
[Id] [int] IDENTITY(1, 1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[Description] [nvarchar](100) NULL
) ON [PRIMARY]
1. 选择更新
update P1
set Name = P2.Name
from Product P1
inner join Product_Bak P2 on p1.id = P2.id
where p1.id = 2
2. 使用公用表表达式进行更新
; With CTE as
(
select id, name from Product_Bak where id = 2
)
update P
set Name = P2.name
from product P inner join CTE P2 on P.id = P2.id
where P2.id = 2
3. 合并
Merge into product P1
using Product_Bak P2 on P1.id = P2.id
when matched then
update set p1.[description] = p2.[description], p1.name = P2.Name;
在这个 Merge 语句中,如果在目标中没有找到匹配的记录,我们可以执行插入,但存在于源中,请查找语法:
Merge into product P1
using Product_Bak P2 on P1.id = P2.id;
when matched then
update set p1.[description] = p2.[description], p1.name = P2.Name;
WHEN NOT MATCHED THEN
insert (name, description)
values(p2.name, P2.description);
评论
您可以在 SQL Server 中使用它进行更新:
UPDATE
T1
SET
T1.col1 = T2.col1,
T1.col2 = T2.col2
FROM
Table1 AS T1
INNER JOIN Table2 AS T2
ON T1.id = T2.id
WHERE
T1.col3 = 'cool'
评论
declare @tblStudent table (id int,name varchar(300))
declare @tblMarks table (std_id int,std_name varchar(300),subject varchar(50),marks int)
insert into @tblStudent Values (1,'Abdul')
insert into @tblStudent Values(2,'Rahim')
insert into @tblMarks Values(1,'','Math',50)
insert into @tblMarks Values(1,'','History',40)
insert into @tblMarks Values(2,'','Math',30)
insert into @tblMarks Values(2,'','history',80)
select * from @tblMarks
update m
set m.std_name=s.name
from @tblMarks as m
left join @tblStudent as s on s.id=m.std_id
select * from @tblMarks
评论
选项 1:使用内部联接:
UPDATE
A
SET
A.col1 = B.col1,
A.col2 = B.col2
FROM
Some_Table AS A
INNER JOIN Other_Table AS B
ON A.id = B.id
WHERE
A.col3 = 'cool'
选项 2:Co 相关子查询
UPDATE table
SET Col1 = B.Col1,
Col2 = B.Col2
FROM (
SELECT ID, Col1, Col2
FROM other_table) B
WHERE
B.ID = table.ID
评论
相同的解决方案可以以略有不同的方式编写,因为我想只设置一次列。我已经写了关于这两张表的文章。它在MySQL中工作。
UPDATE Table t,
(SELECT col1, col2 FROM other_table WHERE sql = 'cool' ) o
SET t.col1 = o.col1, t.col2=o.col2
WHERE t.id = o.id
喜欢这个;但您必须确保更新表和 from 之后的表相同。
UPDATE Table SET col1, col2
FROM table
inner join other_table Table.id = other_table.id
WHERE sql = 'cool'
评论
UPDATE table1
SET column1 = (SELECT expression1
FROM table2
WHERE conditions)
[WHERE conditions];
在 SQL Server 中使用另一个表中的数据更新一个表时 UPDATE 语句的语法。
我以前使用过 INSERT SELECT。对于那些想要使用新东西的人来说,这里有一个类似的解决方案,但它要短得多:
UPDATE table1 // Table that's going to be updated.
LEFT JOIN // Type of join.
table2 AS tb2 // Second table and rename for easy.
ON
tb2.filedToMatchTables = table1.fieldToMatchTables // Fields to connect both tables.
SET
fieldFromTable1 = tb2.fieldFromTable2; // Field to be updated on table1.
field1FromTable1 = tb2.field1FromTable2, // This is in the case you need to
field1FromTable1 = tb2.field1FromTable2, // update more than one field.
field1FromTable1 = tb2.field1FromTable2; // Remember to put ; at the end.
需要指出的是,正如其他人一样,MySQL或MariaDB使用不同的语法。此外,它还支持非常方便的 USING 语法(与 T/SQL 相比)。此外,INNER JOIN 是 JOIN 的同义词。因此,原始问题中的查询最好在MySQL中实现,如下所示:
UPDATE
Some_Table AS Table_A
JOIN
Other_Table AS Table_B USING(id)
SET
Table_A.col1 = Table_B.col1,
Table_A.col2 = Table_B.col2
WHERE
Table_A.col3 = 'cool'
我没有在其他答案中看到所问问题的解决方案,因此我的两美分。(在PHP 7.4.0 MariaDB 10.4.10上测试)
评论
最佳做法:在公司中使用的 SQL Server 中更新行并保存
WITH t AS
(
SELECT UserID, EmailAddress, Password, Gender, DOB, Location,
Active FROM Facebook.Users
)
UPDATE t SET Active = 0
这是更新记录的最安全方法,您可以通过此查看我们将要更新的内容。 来源: URL
评论
Oracle SQL(使用别名):
UPDATE Table T
SET T.col1 = (SELECT OT.col1 WHERE OT.id = T.id),
T.col2 = (SELECT OT.col2 WHERE OT.id = T.id);
对我而言,SQLite3 效果很好,在 INNER SELECT 之后使用 SELECT 更新行。
UPDATE clients
SET col1 = '2023-02-02 18:51:30.826621'
FROM (
SELECT * FROM clients dc WHERE dc.phone NOT IN (
SELECT do.phone FROM dclient_order do WHERE do.order_date > '2023-01-01' GROUP BY do.phone
)
) NewTable
WHERE clients.phone = NewTable.phone;
UPDATE
A
SET
A.col1 = B.col1,
A.col2 = B.col2
FROM
Some_Table AS A
INNER JOIN Other_Table AS B
ON A.id = B.id
WHERE
A.col3 = 'cool'
评论