Làm thế nào để cập nhật từ một SELECT trong SQL Server?


2,848

Trong SQL Server, nó có thể chèn vào một bảng bằng một tuyên bố SELECT:

INSERT INTO Table (col1, col2, col3) 
SELECT col1, col2, col3 
FROM other_table 
WHERE sql = 'cool' 

là nó cũng có thể cập nhật qua một SELECT? Tôi có một bảng tạm thời chứa các giá trị, và muốn cập nhật một bảng khác bằng cách sử dụng các giá trị đó. Có lẽ một cái gì đó như thế này:

UPDATE Table SET col1, col2 
SELECT col1, col2 
FROM other_table 
WHERE sql = 'cool' 
WHERE Table.id = other_table.id 
+3

Nhận xét của Andy là hoàn toàn hợp lệ. Tôi chuyển đổi trang web mysql của tôi sang PDO gần đây nghĩ rằng tôi bây giờ bằng cách nào đó an toàn từ các cuộc tấn công tiêm. Đó là chỉ trong quá trình tôi nhận ra rằng một số báo cáo sql của tôi vẫn được xây dựng bằng cách sử dụng đầu vào của người dùng. Sau đó tôi đã cố định bằng cách sử dụng các câu lệnh đã chuẩn bị. Đối với một người mới hoàn thành, nó không hoàn toàn rõ ràng rằng có một sự phân biệt như nhiều chuyên gia ném ra các bình luận về cách sử dụng PDO nhưng không chỉ định t 23 sep. 172017-09-23 19:01:47

4,193
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' 
+9

Nếu bạn đang chỉnh sửa liên kết giữa các bảng ('SET Table.other_table_id = @ NewValue') sau đó thay đổi câu lệnh ON thành một cái gì đó như 'ON Table.id = @IdToEdit AND other_table.id = @ NewValue' 24 oct. 122012-10-24 18:41:05

+20

Không phải điều này thiếu mệnh đề' WHERE' trong câu hỏi? Tôi không có một máy chủ trên hệ thống này để kiểm tra nó nhưng bạn sẽ không thể thêm nó vào 'ON' như:' ON Table.id = other_table.id AND other_table.sql = 'cool''? Hay tôi hiểu sai câu hỏi? 31 may. 132013-05-31 18:15:58

+9

Điều này hoạt động bằng cách sử dụng UPDATE để lặp qua INNER JOIN. Như vậy các hàm ON như mệnh đề WHERE của bạn và INNER JOIN bỏ qua các bản ghi không được tìm thấy trong bảng JOINed. Thêm mệnh đề WHERE cũng sẽ giới hạn tập kết quả của bảng JOINed. @Roger Ray phiên bản nào của MySQL và truy vấn của bạn là gì, vì hàm DOES này hoạt động như đã nêu. 06 sep. 132013-09-06 17:14:34

+7

@RogerRay, câu hỏi này là về Microsoft SQL Server. Thật không may, cú pháp giữa các triển khai SQL khác nhau có thể khác nhau. 26 nov. 132013-11-26 17:12:20

  0

@CharlesĐúng yeah. Tôi có cùng một câu hỏi trong MySQL. Nó sẽ là tuyệt vời nếu ai đó biết làm thế nào để thực hiện nó để MySQL và chia sẻ với tất cả mọi người. Tôi chắc rằng rất nhiều người đang tìm kiếm giải pháp phiên bản MySQL 27 nov. 132013-11-27 03:34:35

  0

Tôi làm cách nào để sử dụng bí danh trong bộ? bảng cập nhật thiết lập a.col1 = b.col2 từ bảng một bảng nối bên trong2 b trên a.id = b.id; Thay vào đó, tôi phải sử dụng bảng cập nhật thiết lập table.col1 = b.col2 từ bảng một bảng nối bên trong2 b trên a.id = b.id; 20 jan. 142014-01-20 23:08:49

+3

Hơi liên quan, tôi thường thích viết các truy vấn UPDATE của tôi dưới dạng các câu lệnh SELECT trước để tôi có thể xem dữ liệu sẽ được cập nhật trước khi thực thi. Sebastian bao gồm một kỹ thuật cho điều này trong một bài đăng blog gần đây: http: // sqlity.net/en/2867/update-from-select/ 21 aug. 152015-08-21 19:48:36


169

Một cách

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' 

237

Tôi muốn thay đổi câu trả lời tuyệt vời của Robin như sau:

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 
) 

Nếu không có một mệnh đề WHERE, bạn sẽ ảnh hưởng đến các hàng thậm chí không cần phải bị ảnh hưởng, điều này có thể (có thể) gây ra chỉ số tính toán lại hoặc kích hoạt lửa mà thực sự không nên có bị sa thải.

+6

Điều này giả định rằng không có cột nào có giá trị mặc định. 06 nov. 112011-11-06 00:03:32

+3

Bạn nói đúng, tôi đã gõ ví dụ bằng tay. Tôi đã thêm một mệnh đề thứ ba và thứ tư vào câu lệnh where để xử lý điều đó. 11 nov. 112011-11-11 20:27:23

+39

'KHI DANH SÁCH (CHỌN T1.Col1, T1.Col2 CHỌN CHỌN T2.Col1, T2.Col2))' ngắn gọn hơn. 27 may. 122012-05-27 09:44:34

  0

Martin - tôi mất một thời gian để có được sở trường của tuyên bố đó. "Đó là một lựa chọn trong mệnh đề where nhưng nó không phải là một truy vấn con bảng?" là một đề xuất mà tôi gặp khó khăn khi gói não của mình. Bây giờ tôi đã có nó, tôi đã đi để tìm hiểu làm thế nào có giá trị một kỹ thuật nó được, đặc biệt là đối với một số loại hoạt động kho dữ liệu. 03 apr. 132013-04-03 04:53:44

+4

không nên tuyên bố cũng chứa hai trong mệnh đề where? (other_table.col1 là null và table.col1 không phải là null) hoặc (other_table.col2 là null và table.col2 không phải là null) 15 may. 132013-05-15 04:03:29

+3

Phụ thuộc vào nếu bạn muốn thay thế null trong đích bằng null từ nguồn. Thường xuyên, tôi không. Nhưng nếu bạn làm, Martin xây dựng mệnh đề where là điều tốt nhất để sử dụng. 16 may. 132013-05-16 16:35:50


37

Tôi chỉ thêm tùy chọn này để bạn có thể xem cách viết nhanh để bạn có thể kiểm tra nội dung sẽ được cập nhật trước khi thực hiện cập nhật.

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 

638

Trong SQL Server 2008 (hoặc tốt hơn), sử dụng 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; 

Hoặc:

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; 
+103

'MERGE' cũng có thể được sử dụng cho các bản ghi" Upserting "; có nghĩa là, 'UPDATE' nếu bản ghi phù hợp tồn tại,' INSERT' bản ghi mới nếu không có kết quả nào được tìm thấy 15 may. 122012-05-15 19:51:44

+15

Đây là khoảng 10 lần nhanh hơn bản cập nhật tương đương ... tuyên bố kết hợp cho tôi. 03 apr. 132013-04-03 02:49:54

+16

MERGE cũng có thể được sử dụng để XÓA. Nhưng hãy cẩn thận với MERGE vì bảng TARGET không thể là một bảng từ xa. 08 aug. 132013-08-08 03:58:09

+1

Cảm ơn vì điều này, đã không nhìn thấy 'MERGE' chắc chắn giống như cú pháp, và bạn có thể sử dụng bí danh (không hoạt động trong bản cập nhật/set/from) tốt hơn nhiều ... Tôi đã sử dụng' WITH' báo cáo cho phần truy vấn. 20 feb. 142014-02-20 16:48:06

  0

Nếu tôi không thể đảm bảo kết quả của một hợp nhất, và tôi có thể guarnatee kết quả của việc làm riêng biệt chèn và cập nhật statments, sau đó nó là một ý tưởng tồi để sử dụng hợp nhất. 02 jun. 142014-06-02 13:34:20

+1

@ HLGEM: ... Tôi giả sử bạn biết trường hợp kết quả của 'UPDATE..FROM' không được bảo đảm? (gợi ý: nhiều bên của một-to-nhiều tham gia, nơi kết quả là tùy ý) Đó là loại 'lỗi' bạn đang ám chỉ? 19 jun. 142014-06-19 10:59:05

+11

@SimonD: chọn bất kỳ từ khóa SQL Server nào và bạn sẽ tìm thấy lỗi. Điểm của bạn? Tôi cược có nhiều lỗi hơn (và nhiều lỗi cơ bản nữa) liên quan đến 'UPDATE' hơn' MERGE', mọi người đã học cách sống với họ và họ trở thành một phần của cảnh quan ('tính năng'). Hãy xem xét rằng các blog không tồn tại khi 'UPDATE' là đứa trẻ mới trên khối. 03 oct. 142014-10-03 15:29:09

+2

@SimonD Tôi chắc chắn bạn sẽ có thể tìm thấy các vấn đề tương tự như những lỗi "MERGE" (cũng ...) trong combo INSERT/UPDATE/DELETE riêng biệt. Một điều - luôn luôn sử dụng MERGE trong giao dịch SERIALIZABLE (hoặc sử dụng gợi ý HOLDLOCK) nếu bạn muốn tránh các điều kiện chủng tộc phổ biến nhất. Tương tự cho việc hợp nhất thủ công bằng INSERT/UPDATE/DELETE ... 26 nov. 142014-11-26 11:36:43

+1

Lưu ý về di động: [MERGE] (https://en.wikipedia.org/wiki/Merge_ (SQL)) là ANSI SQL; [CẬP NHẬT ... TỪ] (https://en.wikipedia.org/wiki/Update_ (SQL)) thì không. Có sử dụng cả hai, tôi tìm thấy ngữ nghĩa MERGE dễ hiểu hơn - Tôi ít có khả năng làm rối tung lên một MERGE hơn là một UPDATE ... TỪ. YMMV. 10 oct. 172017-10-10 14:22:25


129

Một khả năng khác không được đề cập chưa được chỉ chuck tuyên bố SELECT mình thành một CTE sau đó cập nhật 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 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 

này có những lợi ích mà nó rất dễ dàng để chạy báo cáo kết quả SELECT trên đầu riêng của mình để tỉnh táo kiểm tra kết quả nhưng nó đòi hỏi bạn phải bí danh cột như trên nếu họ được đặt tên giống nhau ở nguồn và đích những cái bàn.

Điều này cũng có cùng giới hạn như cú pháp độc quyền UPDATE ... FROM được hiển thị trong bốn câu trả lời khác. Nếu bảng nguồn nằm ở phía nhiều của một đến nhiều tham gia thì không xác định được bản ghi đã kết hợp nào có thể được sử dụng trong Update (Một vấn đề mà MERGE tránh bằng cách tăng lỗi nếu có cố gắng cập nhật cùng một hàng nhiều lần).

+1

là có bất kỳ ý nghĩa của tên 'CTE'? 08 oct. 122012-10-08 12:48:00

+13

@ShivanRaptor - Đây là từ viết tắt của [Biểu thức bảng chung] (http://msdn.microsoft.com/en-us/library/ms190766 (v = sql.105) .aspx). Chỉ là một bí danh tùy ý trong trường hợp này. 08 oct. 122012-10-08 13:05:15

+2

Điều này cũng hoạt động tốt với nhiều CTE: '; VỚI SomeCompexCTE AS (...), CTEAsAbove AS (SELECT T1.Col1, ... TỪ T1 JOIN SomeComplexCTE ...) CẬP NHẬT CTEAsAbove SET Col1 = _Col1, ...' 29 aug. 132013-08-29 20:09:10


494
UPDATE table 
SET Col1 = i.Col1, 
    Col2 = i.Col2 
FROM (
    SELECT ID, Col1, Col2 
    FROM other_table) i 
WHERE 
    i.ID = table.ID 
+5

Cho đến nay đơn giản nhất! Tuy nhiên, bạn thiếu trường ** ID ** từ SELECT bên trong. Bạn sẽ cần điều này cho mệnh đề WHERE để làm việc 31 oct. 142014-10-31 18:03:20

+7

Điều này sẽ có xu hướng làm việc trên hầu như tất cả các DBMS có nghĩa là tìm hiểu một lần, thực hiện ở khắp mọi nơi. Nếu điều đó quan trọng đối với bạn hơn hiệu suất, bạn có thể thích câu trả lời này, đặc biệt nếu bản cập nhật của bạn là một phần tắt để sửa một số dữ liệu. 01 feb. 162016-02-01 14:46:33

  0

@ dotnetN00b https://stackoverflow.com/a/2334741/206730 không tốt cho bạn? 29 nov. 172017-11-29 14:45:35


69

Sử dụng bí danh:

UPDATE t 
SET t.col1 = o.col1 
FROM 
    table1 AS t 
INNER JOIN table2 AS o ON t.id = o.id 

43

Đây có thể là một lý do thích hợp để thực hiện một bản cập nhật (ví dụ, chủ yếu được sử dụng trong một thủ tục), hoặc có thể là hiển nhiên đối với những người khác, nhưng nó cũng nên đã tuyên bố rằng bạn có thể thực hiện câu lệnh chọn cập nhật mà không cần sử dụng phép nối (trong trường hợp các bảng bạn đang cập nhật giữa không có trường chung).

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 

85

Đối với hồ sơ (và những người khác tìm kiếm như tôi đã được), bạn có thể làm điều đó trong MySQL như thế này:

UPDATE first_table, second_table 
SET first_table.color = second_table.color 
WHERE first_table.id = second_table.foreign_id 
+4

Điều này hoạt động tốt. Tôi đã thử tất cả các truy vấn trên, tất cả đều cho một hoặc một loại lỗi khác. 02 sep. 142014-09-02 15:24:01

+3

Cảm ơn bạn! Tôi biết đây là cũ, nhưng chỉ muốn nói điều này làm việc cho tôi. Máy chủ của tôi sẽ không cho phép FROM được sử dụng trong câu lệnh UPDATE. Vì vậy, tất cả các câu trả lời liên quan đến mệnh đề FROM trả lại một lỗi cú pháp. Cách này làm việc hoàn hảo. Nhiều đánh giá cao. 09 sep. 142014-09-09 17:32:53

+3

Tại sao điều này lại được bình chọn nhiều như vậy?Sẽ là như vậy nếu tôi đăng cho mã ruby ​​hồ sơ nếu ai đó yêu cầu C# ... 09 mar. 162016-03-09 17:10:33

+1

@isHuman Nó là rất phổ biến để đạt được trong một câu hỏi sql-server khi bạn tìm kiếm câu trả lời my-sql (và ngược lại). Nó hoàn toàn khác với việc đăng câu trả lời ruby ​​trong câu hỏi C#. 25 oct. 172017-10-25 18:46:59


52

Cách đơn giản để làm điều đó là:

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 
+1

Bạn được định dạng tốt hơn; Ngoài ra, khi sử dụng một subselect, của bạn (và của Adrian) làm việc đáng tin cậy hơn so với định dạng khác. Cảm ơn bạn đã đăng câu trả lời của mình. 14 feb. 132013-02-14 22:11:45

+14

Đây không phải là cú pháp Máy chủ SQl và nó sẽ không hoạt động trong máy chủ SQL 24 apr. 132013-04-24 18:32:10


41

Dưới đây là một cú pháp hữu ích khác:

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); 

Nó chec ks nếu nó là null hoặc không bằng cách sử dụng "WHERE EXIST".


27

Ví dụ sau sử dụng một bảng có nguồn gốc, một câu lệnh SELECT sau mệnh đề FROM, để trả lại giá trị cũ và mới để cập nhật thêm:

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 

37

Nếu bạn sử dụng MySQL thay vì SQL Server, cú pháp là :

UPDATE Table1 
INNER JOIN Table2 
ON Table1.id = Table2.id 
SET Table1.col1 = Table2.col1, 
    Table1.col2 = Table2.col2 
+15

Không phải là ý tưởng tốt nhất để sử dụng từ khóa "bảng" làm tên bảng mẫu. Một số người dùng ít kinh nghiệm hơn có thể thấy ví dụ này khó hiểu. 15 dec. 142014-12-15 22:21:01


11
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 

DÙ:

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') 

OR:

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 

Nếu tên cột ID là như nhau trong cả hai bảng sau đó chỉ cần đặt tên bảng trước bảng để được cập nhật và sử dụng một bí danh cho bảng tức là chọn:

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') 

27

Và nếu bạn muốn tham gia bàn với chính nó (mà sẽ không xảy ra quá thường xuyên):

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 
+7

+1 nhưng bạn nên sử dụng tên bí danh có liên quan như 'targett1' và' sourcet1' thay vì (hoặc cũng như) nhận xét. 30 jun. 142014-06-30 02:05:36


10

cuối cùng tôi nhận được giải pháp đơn giản này:

01.
UPDATE table1 a , table2 b 
SET a.columname = 'some value' 
WHERE b.columnname IS NULL ; 
+3

Không hoạt động trong MS SQL Server 17 jun. 162016-06-17 07:04:37


8
UPDATE table AS a 
INNER JOIN table2 AS b 
ON a.col1 = b.col1 
INNER JOIN ... AS ... 
ON ... = ... 
SET ... 
WHERE ... 
+1

Định dạng này là những gì hoạt động trong MS Access. Đặt JOIN ở cuối sẽ nhận được thông báo lỗi "Syntax error (missing operator)". Các ví dụ khác tại đây: https://www.fmsinc.com/microsoftaccess/query/snytax/update-query.html 18 mar. 162016-03-18 14:31:32


29

CẬP NHẬT từ SELECT với INNER JOIN trong cơ sở dữ liệu SQL

Vì có quá nhiều trả lời của bài viết này, đó là nặng nề nhất lên-bình chọn, tôi nghĩ tôi sẽ cung cấp gợi ý của tôi ở đây quá. Mặc dù câu hỏi là rất thú vị, tôi đã thấy trong nhiều trang web diễn đàn và đã thực hiện một giải pháp sử dụng INNER JOIN với ảnh chụp màn hình.

Lúc đầu, tôi đã tạo một bảng có tên là schoolold và chèn một vài bản ghi liên quan đến tên cột của chúng và thực thi nó.

Sau đó, tôi đã thực hiện SELECT lệnh để xem các bản ghi được chèn.

enter image description here

Sau đó, tôi đã tạo ra một bảng mới có tên với schoolnew và tương tự thực hiện các thao tác trên nó ở trên.

enter image description here

Sau đó, để xem hồ sơ lắp vào nó, tôi thực hiện CHỌN lệnh.

enter image description here

Bây giờ, Ở đây tôi muốn thực hiện một số thay đổi trong hàng thứ ba và thứ tư, để hoàn tất hành động này, tôi thực hiện CẬP NHẬT lệnh với INNER JOIN.

enter image description here

Để xem những thay đổi tôi thực hiện CHỌN lệnh.

enter image description here

Bạn có thể xem như thế nào Thứ ba và thứ tư kỷ lục của bảng schoolold dễ dàng thay thế bằng bảng schoolnew bằng cách sử dụng INNER JOIN với câu lệnh UPDATE.


24

Đang cập nhật thông qua CTE là dễ đọc hơn so với câu trả lời khác là ở đây:

;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 

14

Một cách khác là sử dụng một bảng có nguồn gốc:

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 

dữ liệu mẫu

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 

10
The other way to update from select statement : 

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' 
+3

_Một cách khác để cập nhật từ câu lệnh select_ Sự khác biệt với các câu trả lời khác là gì? Hãy xây dựng câu trả lời của bạn. Lưu ý: ** Câu trả lời hay ** sẽ luôn có giải thích về những gì đã được thực hiện và tại sao nó được thực hiện theo cách như vậy, không chỉ cho OP mà đối với khách truy cập trong tương lai đối với SO. 08 sep. 162016-09-08 12:29:58

  0

Câu trả lời này được bật lên trong hàng đợi đánh giá chất lượng thấp, có lẽ vì bạn không cung cấp bất kỳ lời giải thích nào về mã. Nếu mã này trả lời câu hỏi, hãy cân nhắc việc thêm một số văn bản giải thích mã trong câu trả lời của bạn. Bằng cách này, bạn có nhiều khả năng nhận được nhiều upvotes hơn - và giúp người hỏi tìm hiểu điều gì đó mới mẻ. 08 sep. 162016-09-08 22:09:31


13
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 

Để đảm bảo bạn được cập nhật những gì bạn muốn, chọn đầu tiên

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 

11

Thậm chí còn có một phương pháp ngắn hơn và có thể gây ngạc nhiên cho nhiều bạn:

-- Sample data: 
--------------------------------------------------------------------------- 
CREATE TABLE #SOURCE ([ID] INT, [Desc] VARCHAR(10)); 
CREATE TABLE #DESTINATION ([ID] INT, [Desc] VARCHAR(10)) 

INSERT INTO #SOURCE VALUES(1,'Desc_1'), (2, 'Desc_2'), (3, 'Desc_3'); 
INSERT INTO #DESTINATION VALUES(1,'Desc_4'), (2, 'Desc_5'), (3, 'Desc_6'); 
--------------------------------------------------------------------------- 
UPDATE #DESTINATION 
SET #DESTINATION.[Desc] = #SOURCE.[Desc] 
FROM #SOURCE 
WHERE #DESTINATION.[ID] = #SOURCE.[ID] 
AND #Source.[Desc] = 'Desc_2' 
+1

CÓ - không có mục đích JOIN và NO - điều này không thể được áp dụng trên các biến bảng. 26 jan. 172017-01-26 13:30:28

+1

Tôi nghĩ rằng nếu bạn sử dụng [_id] trên #SOURCE của bạn không phải [ID] giống với # DESTINATION, họ có thể cho phép bạn tham gia THAM GIA. "trên # DESTINATION.ID = # SOURCE._id. Hoặc thậm chí sử dụng biến bảng như @tbl," trên [email protected]_id ". Bạn đã thử chưa? Tôi đang sử dụng điện thoại để trả lời câu hỏi này, không có máy tính nào để thử 03 feb. 172017-02-03 15:53:31

+1

Điều này có liên quan gì đến việc cập nhật từ một SELECT? 05 feb. 172017-02-05 18:10:07

+1

Đây là ý tưởng tương tự nhưng một phương pháp khác - bạn không phải đặt "chọn" ở tất cả để đạt được JOIN và WHERE trong câu lệnh cập nhật - đó là loại SELECT truy vấn mà không cần phải viết SELECT 05 feb. 172017-02-05 18:19:13


21

Nếu bạn đang sử dụng SQL Server, bạn có thể cập nhật một bảng từ bảng khác mà không chỉ định một phép nối và chỉ cần liên kết hai từ mệnh đề where. Điều này làm cho một truy vấn đơn giản hơn nhiều SQL:

UPDATE Table1 
SET Table1.col1 = Table2.col1, 
Table1.col2 = Table2.col2 
FROM 
    Table2 
WHERE 
    Table1.id = Table2.id 
  0

Câu trả lời này khác với câu trả lời của tôi như thế nào? :) 11 jan. 182018-01-11 13:35:19


9

Trong câu trả lời được chấp nhận, sau khi:

SET 
Table_A.col1 = Table_B.col1, 
Table_A.col2 = Table_B.col2 

tôi sẽ thêm:

OUTPUT deleted.*, inserted.* 

Những gì tôi thường làm là đặt tất cả mọi thứ trong một rollbacked giao dịch và sử dụng "OUTPUT": theo cách này tôi thấy mọi thứ sắp xảy ra. Khi tôi hài lòng với những gì tôi thấy, tôi thay đổi ROLLBACK thành COMMIT.

Tôi thường cần ghi lại những gì tôi đã làm, vì vậy tôi sử dụng tùy chọn "kết quả thành văn bản" khi tôi chạy truy vấn được khôi phục và tôi lưu cả tập lệnh và kết quả của OUTPUT.(Tất nhiên điều này là không thực tế nếu tôi đã thay đổi quá nhiều hàng)


0

phương pháp tiếp cận khác nhau có -

  1. Chọn Cập nhật
  2. Cập nhật với Bảng Common Biểu
  3. Merge

Mẫu Bảng Cấu trúc:

Sản phẩm

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. Chọn Cập nhật

update P1 
    set Name=P2.Name 
    from Product P1 
    inner join Product_Bak P2 on p1.id=P2.id 
    where p1.id=2 

2. Cập nhật với Bảng Common Biểu

;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

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; 

Trong tuyên bố Merge, chúng ta có thể làm inset nếu không tìm thấy phù hợp với kỷ lục trong Target nhưng tồn tại trong nguồn và hãy tìm ông cú pháp.

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);