How do I UPDATE from a SELECT in SQL Server?
在SQL Server中,可以使用
1 2 3 4 | INSERT INTO TABLE (col1, col2, col3) SELECT col1, col2, col3 FROM other_table WHERE SQL = 'cool' |
是否也可以通过
1 2 3 4 5 | UPDATE TABLE SET col1, col2 SELECT col1, col2 FROM other_table WHERE SQL = 'cool' WHERE TABLE.id = other_table.id |
1 2 3 4 5 6 7 8 9 10 11 | 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' |
在SQL Server 2008(或更高版本)中,使用
1 2 3 4 5 6 7 8 | 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; |
可选地:
1 2 3 4 5 6 7 8 9 10 11 | 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; |
1 2 3 4 5 6 7 8 | UPDATE TABLE SET Col1 = i.Col1, Col2 = i.Col2 FROM ( SELECT ID, Col1, Col2 FROM other_table) i WHERE i.ID = TABLE.ID |
我将修改罗宾对以下问题的完美回答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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子句,即使不需要受影响的行也会受到影响,这可能(可能)导致重新计算索引或激发真正不应该激发的触发器。
单程
1 2 3 4 5 6 7 8 9 | 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' |
另一个尚未提到的可能性是将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ;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 |
这样做的好处是,可以很容易地单独运行
这与其他四个答案中显示的专有
对于记录(以及其他像我这样的搜索),您可以在MySQL中这样做:
1 2 3 | UPDATE first_table, second_table SET first_table.color = second_table.color WHERE first_table.id = second_table.foreign_id |
使用别名:
1 2 3 4 5 6 | UPDATE t SET t.col1 = o.col1 FROM table1 AS t INNER JOIN table2 AS o ON t.id = o.id |
简单的方法是:
1 2 3 4 5 6 7 8 9 | 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 |
这可能是执行更新(例如,主要用于某个过程)的特定原因,或者对其他人来说是显而易见的,但也应该说明,您可以在不使用join的情况下执行update select语句(如果您正在更新的表之间没有公共字段)。
1 2 3 4 5 6 7 8 9 | 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 |
下面是另一个有用的语法:
1 2 3 4 5 6 7 | 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"检查是否为空。
我添加这个只是为了让你能看到一个快速的方法来写它,这样你就可以在进行更新之前检查将要更新的内容。
1 2 3 4 5 6 7 | 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 |
如果使用MySQL而不是SQL Server,则语法为:
1 2 3 4 5 | UPDATE Table1 INNER JOIN Table2 ON Table1.id = Table2.id SET Table1.col1 = Table2.col1, Table1.col2 = Table2.col2 |
在SQL数据库中使用内部联接从select更新
因为这篇文章的回复太多了,而且投票最多,所以我想我也会在这里提出我的建议。尽管这个问题很有趣,但我在许多论坛网站上都看到过,并用截图进行了内部连接的解决方案。
首先,我创建了一个名为schooldold的表,并插入了一些与列名相关的记录,然后执行它。
然后我执行了select命令来查看插入的记录。
如果您想将表与其自身连接起来(这种情况不会太频繁):
1 2 3 4 5 | 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 |
以下示例使用派生表(FROM子句后的select语句)返回旧值和新值以进行进一步更新:
1 2 3 4 5 6 7 8 9 10 | 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 |
通过
1 2 3 4 5 6 7 8 9 10 | ;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 |
如果您使用的是SQL Server,那么您可以在不指定联接的情况下从另一个表更新一个表,并且只需从
1 2 3 4 5 6 7 | UPDATE Table1 SET Table1.col1 = Table2.col1, Table1.col2 = Table2.col2 FROM Table2 WHERE Table1.id = Table2.id |
另一种方法是使用派生表:
1 2 3 4 5 6 | 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 |
样本数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 |
1 2 3 4 5 | 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 |
要确保正在更新所需内容,请首先选择
1 2 3 4 | 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 |
用途:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 |
要么:
1 2 | 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') |
或:
1 2 3 4 5 | 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列名相同,则只需将表名放在要更新的表之前,并为所选表使用别名,即:
1 2 | 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') |
甚至还有一种更短的方法,可能会让您感到惊讶:
示例数据集:
1 2 3 4 5 | 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'); |
代码:
1 2 3 4 | UPDATE #DEST SET #DEST.[DESC] = #SOURCE.[DESC] FROM #SOURCE WHERE #DEST.[ID] = #SOURCE.[ID]; |
在接受的回答中,在以下时间之后:
1 2 3 | SET Table_A.col1 = Table_B.col1, Table_A.col2 = Table_B.col2 |
我补充说:
1 | OUTPUT deleted.*, inserted.* |
我通常做的是将所有内容放入一个滚动备份的事务中,并使用
我通常需要记录我所做的,所以在运行回滚查询时使用
从select语句更新的另一种方法:
1 2 3 4 | 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' |
1 2 3 4 5 6 7 | UPDATE TABLE AS a INNER JOIN table2 AS b ON a.col1 = b.col1 INNER JOIN ... AS ... ON ... = ... SET ... WHERE ... |
在这里整合所有不同的方法。
示例表结构如下,将从product_k更新到product表。
产品1 2 3 4 5 | CREATE TABLE [dbo].[Product]( [Id] [INT] IDENTITY(1, 1) NOT NULL, [Name] [nvarchar](100) NOT NULL, [Description] [nvarchar](100) NULL ) ON [PRIMARY] |
产品制造商
1 2 3 4 5 | CREATE TABLE [dbo].[Product_BAK]( [Id] [INT] IDENTITY(1, 1) NOT NULL, [Name] [nvarchar](100) NOT NULL, [Description] [nvarchar](100) NULL ) ON [PRIMARY] |
1。选择更新
1 2 3 4 5 | UPDATE P1 SET Name = P2.Name FROM Product P1 INNER JOIN Product_Bak P2 ON p1.id = P2.id WHERE p1.id = 2 |
2。使用公用表表达式更新
1 2 3 4 5 6 7 8 | ; 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 |
三。合并
1 2 3 4 5 | 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语句中,如果在目标中找不到匹配的记录,但源中存在,则可以执行插入操作,请查找语法:
1 2 3 4 5 6 7 8 9 | 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); |
以下解决方案适用于MySQL数据库:
1 2 3 | UPDATE table1 a , table2 b SET a.columname = 'some value' WHERE b.columnname IS NULL ; |
选项1:使用内部联接:
1 2 3 4 5 6 7 8 9 10 11 | 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:共同相关子查询
1 2 3 4 5 6 7 8 | UPDATE TABLE SET Col1 = B.Col1, Col2 = B.Col2 FROM ( SELECT ID, Col1, Col2 FROM other_table) B WHERE B.ID = TABLE.ID |
1 2 3 4 5 | UPDATE table1 SET column1 = (SELECT expression1 FROM table2 WHERE conditions) [WHERE conditions]; |
使用SQL Server中另一个表的数据更新一个表时,update语句的语法
您可以在SQL Server中使用此更新
1 2 3 4 5 6 7 8 9 10 11 | 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' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 2 3 4 | UPDATE TABLE SET col1, col2 FROM TABLE INNER JOIN other_table TABLE.id = other_table.id WHERE SQL = 'cool' |
相同的解决方案可以用稍微不同的方式编写,因为我只想在编写了两个表之后设置列。在MySQL中工作。
1 2 3 4 | 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 |