ฉันจะอัพเดทจาก SELECT ใน SQL Server ได้อย่างไร


3694

ในSQL Serverเป็นไปได้ที่จะINSERTเข้าไปในตารางโดยใช้SELECTคำสั่ง:

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

เป็นไปได้ไหมที่จะอัพเดทผ่าน a SELECT? ฉันมีตารางชั่วคราวที่มีค่าและต้องการอัปเดตตารางอื่นโดยใช้ค่าเหล่านั้น บางทีสิ่งนี้:

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

คำตอบ:


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

16
หากคุณกำลังแก้ไขการเชื่อมโยงระหว่างตาราง ( SET Table.other_table_id = @NewValue) จากนั้นเปลี่ยนคำสั่ง ON เป็นสิ่งที่ต้องการON Table.id = @IdToEdit AND other_table.id = @NewValue
Trisped

11
@RogerRay คำถามนี้เกี่ยวกับ Microsoft SQL Server น่าเสียดายที่ไวยากรณ์ระหว่างการปรับใช้ SQL แบบต่างๆสามารถแตกต่างกันได้
Charles Wood

2
@CharlesWood ใช่ ฉันมีคำถามเดียวกันใน MySQL มันจะดีถ้ามีคนรู้วิธีนำไปใช้กับ MySQL และแบ่งปันกับทุกคน ฉันแน่ใจว่าผู้คนจำนวนมากกำลังมองหาโซลูชันรุ่น MySQL
Roger Ray

1
ฉันจะใช้ชื่อแทนในชุดได้อย่างไร ตั้งค่าตารางการอัพเดต a.col1 = b.col2 จากตาราง a เข้าร่วม table2 b บน a.id = b.id; แต่ฉันต้องใช้ชุดตารางการปรับปรุง table.col1 = b.col2 จากตาราง a เข้าร่วม table2 b ใน a.id = b.id;
ThinkCode

11
ค่อนข้างเกี่ยวข้องกันฉันมักจะเขียนแบบสอบถาม UPDATE ของฉันเป็นคำสั่ง SELECT ก่อนเพื่อให้ฉันสามารถดูข้อมูลที่จะได้รับการอัปเดตก่อนที่ฉันจะเรียกใช้งาน เซบาสเตียนครอบคลุมเทคนิคนี้ในบล็อกโพสต์เมื่อเร็ว ๆ นี้: sqlity.net/th/2867/update-from-select
dennislloydjr

777

ใน 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;

122
MERGEนอกจากนี้ยังสามารถใช้สำหรับการบันทึก "Upserting"; นั่นคือUPDATEถ้ามีระเบียนที่ตรงกันอยู่ระเบียนINSERTใหม่ถ้าไม่พบที่ตรงกัน
brichins

16
นี่เป็นประมาณ 10 เท่าเร็วกว่าการอัปเดตที่เทียบเท่า ... เข้าร่วมคำสั่งสำหรับฉัน
Paul Suart

17
MERGE สามารถใช้เพื่อลบ แต่ระวังด้วย MERGE เนื่องจากตาราง TARGET ไม่สามารถเป็นตารางระยะไกลได้
Möoz

24
รวมข้อผิดพลาด: mssqltips.com/sqlservertip/3074/…
Simon D

16
@SimonD: เลือกคีย์เวิร์ด SQL Server ใด ๆ แล้วคุณจะพบข้อบกพร่อง ประเด็นของคุณ? ฉันเดิมพันมีข้อผิดพลาดเพิ่มเติม (และพื้นฐานมากกว่าเช่นกัน) ที่เกี่ยวข้องกับUPDATEกว่าMERGEคนเพิ่งเรียนรู้ที่จะอยู่กับพวกเขาและพวกเขากลายเป็นส่วนหนึ่งของภูมิทัศน์ ('คุณสมบัติ') พิจารณาว่าบล็อกไม่มีอยู่เมื่อUPDATEเป็นเด็กใหม่ในบล็อก
oneday เมื่อ

673
UPDATE YourTable 
SET Col1 = OtherTable.Col1, 
    Col2 = OtherTable.Col2 
FROM (
    SELECT ID, Col1, Col2 
    FROM other_table) AS OtherTable
WHERE 
    OtherTable.ID = YourTable.ID

7
โดยง่ายที่สุด! อย่างไรก็ตามคุณขาดหายไปจากช่องIDจากภายในเลือก คุณจะต้องใช้สิ่งนี้เพื่อให้ WHERE clause ทำงานได้
John Doherty

12
สิ่งนี้จะมีแนวโน้มที่จะทำงานกับ DBMS เกือบทั้งหมดซึ่งหมายถึงการเรียนรู้เพียงครั้งเดียว หากนั่นสำคัญกับคุณมากกว่าประสิทธิภาพคุณอาจต้องการคำตอบนี้โดยเฉพาะอย่างยิ่งหากการอัปเดตของคุณเป็นข้อมูลที่ถูกต้องสำหรับการแก้ไขข้อมูลบางอย่าง
Alan Macdonald

2
หากคุณต้องการตั้งค่าตารางแรกด้วยผลรวมจากวินาทีคุณสามารถใส่ผลรวมในแบบสอบถามย่อยที่เลือกเนื่องจากคุณไม่สามารถทำได้SET Table_A.col1 = SUM(Table_B.col1)(หรือฟังก์ชั่นรวมอื่น ๆ ) ดีกว่าคำตอบของ Robin Day สำหรับจุดประสงค์นี้
Jason S

280

ฉันจะแก้ไขคำตอบที่ยอดเยี่ยมของ 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 คุณจะได้รับผลกระทบแม้กระทั่งแถวที่ไม่จำเป็นต้องได้รับผลกระทบซึ่งอาจเป็นสาเหตุให้เกิดการคำนวณดัชนีใหม่หรือทริกเกอร์ไฟที่ไม่ควรถูกไล่ออก


7
สิ่งนี้ถือว่าไม่มีคอลัมน์ใดที่เป็นโมฆะ
Martin Smith

4
คุณพูดถูกฉันพิมพ์ตัวอย่างด้วยมือ ฉันได้เพิ่มประโยคที่สามและสี่ในคำสั่ง where เพื่อจัดการกับสิ่งนั้น
quillbreaker

46
WHERE EXISTS(SELECT T1.Col1, T1.Col2 EXCEPT SELECT T2.Col1, T2.Col2))กระชับยิ่งขึ้น
Martin Smith

5
คำสั่งไม่ควรมีทั้งสองนี้ในส่วนคำสั่งหรือไม่ (other_table.col1 เป็นโมฆะและ table.col1 ไม่ใช่โมฆะ) หรือ (other_table.col2 เป็นโมฆะและ table.col2 ไม่เป็นโมฆะ)
Barka

4
ขึ้นอยู่กับว่าคุณต้องการแทนที่โมฆะในปลายทางด้วยโมฆะจากแหล่งที่มา บ่อยครั้งที่ฉันทำไม่ได้ แต่ถ้าคุณทำมาร์ตินก่อสร้างประโยคที่เป็นสิ่งที่ดีที่สุดที่จะใช้
quillbreaker


165

ความเป็นไปได้อื่น ๆ ที่ยังไม่ได้กล่าวถึงคือการโยน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 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หลีกเลี่ยงโดยการเพิ่มข้อผิดพลาดหากมีความพยายามปรับปรุง แถวเดียวกันมากกว่าหนึ่งครั้ง)


3
ความหมายของชื่อมีCTEอะไรบ้าง?
Raptor

19
@ShivanRaptor - มันเป็นตัวย่อสำหรับตารางนิพจน์ทั่วไป เพียงนามแฝงโดยพลการในกรณีนี้
Martin Smith

3
สิ่งนี้ยังทำงานได้ดีกับ CTE หลายรายการ:;WITH SomeCompexCTE AS (...), CTEAsAbove AS (SELECT T1.Col1,... FROM T1 JOIN SomeComplexCTE...) UPDATE CTEAsAbove SET Col1=_Col1, ...
VeeTheSecond

117

สำหรับบันทึก (และคนอื่น ๆ ที่กำลังค้นหาฉัน) คุณสามารถทำได้ใน MySQL เช่นนี้:

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

ง่ายที่สุด? ขอบคุณ ...
MarcoZen


73

วิธีง่ายๆในการทำคือ:

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

2
รูปแบบของคุณดีขึ้น; นอกจากนี้เมื่อใช้การเลือกย่อยของคุณ (และเอเดรียน) จะทำงานได้อย่างน่าเชื่อถือมากกว่ารูปแบบอื่น ๆ ขอบคุณสำหรับการโพสต์คำตอบของคุณ
เบ็นเวสต์

20
นี่ไม่ใช่ไวยากรณ์ของเซิร์ฟเวอร์ SQl และจะไม่ทำงานในเซิร์ฟเวอร์ SQL
HLGEM

สิ่งนี้ทำงานได้ดีใน SQL Alchemy อาจไม่ใช่คำถามที่ถาม แต่ช่วยได้แน่นอน :)
JGTaylor

61

นี่อาจเป็นเหตุผลเฉพาะในการอัปเดต (ตัวอย่างเช่นส่วนใหญ่ที่ใช้ในกระบวนการ) หรืออาจเห็นได้ชัดกับผู้อื่น แต่ก็ควรระบุด้วยว่าคุณสามารถดำเนินการคำสั่ง 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

59

นี่คือไวยากรณ์ที่มีประโยชน์อื่น:

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

มันจะตรวจสอบว่ามันเป็นโมฆะหรือไม่โดยใช้ "อยู่ที่ไหน"


52

ฉันเพิ่มสิ่งนี้เท่านั้นเพื่อให้คุณเห็นวิธีที่รวดเร็วในการเขียนเพื่อให้คุณสามารถตรวจสอบสิ่งที่จะได้รับการอัปเดตก่อนทำการอัปเดต

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 

52

ถ้าคุณใช้MySQLแทน SQL Server ไวยากรณ์คือ:

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

50

อัปเดตจาก SELECT ด้วย INNER JOIN ในฐานข้อมูล SQL

เนื่องจากมีคำตอบของโพสต์นี้มากเกินไปซึ่งได้รับการโหวตมากที่สุดฉันคิดว่าฉันจะให้คำแนะนำที่นี่ด้วย แม้ว่าคำถามจะน่าสนใจมาก แต่ฉันได้เห็นในไซต์ฟอรัมหลายแห่งและได้แก้ปัญหาโดยใช้INNER JOINพร้อมภาพหน้าจอ

ตอนแรกฉันสร้างตารางที่มีชื่อschoololdและแทรกเร็กคอร์ดเล็กน้อยที่เกี่ยวข้องกับชื่อคอลัมน์และดำเนินการ

จากนั้นฉันเรียกใช้คำสั่งSELECTเพื่อดูเร็กคอร์ดที่แทรก

จากนั้นฉันก็สร้างตารางใหม่ที่มีชื่อว่าโรงเรียนและดำเนินการอย่างเดียวกันกับข้างบน

จากนั้นเมื่อต้องการดูบันทึกที่ใส่เข้าไปฉันจะใช้คำสั่ง SELECT

ตอนนี้ที่นี่ฉันต้องการที่จะทำให้การเปลี่ยนแปลงบางอย่างในแถวที่สามและสี่เพื่อให้การดำเนินการนี้ผมดำเนินการปรับปรุงคำสั่งกับINNER JOIN

เพื่อดูการเปลี่ยนแปลงที่ฉันดำเนินการคำสั่งSELECT

คุณสามารถดูว่าระเบียนที่สามและสี่ของตารางโรงเรียนถูกแทนที่ได้อย่างง่ายดายด้วยตารางโรงเรียนใหม่โดยใช้ INNER JOIN ด้วยคำสั่ง UPDATE


43

และถ้าคุณต้องการที่จะเข้าร่วมโต๊ะกับตัวเอง (ซึ่งจะไม่เกิดขึ้นบ่อยเกินไป):

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

8
+1 แต่คุณควรใช้ชื่อนามแฝงที่เกี่ยวข้องเช่นtargett1และsourcet1(หรือรวมถึง) ความคิดเห็น
Mark Hurd

42

ตัวอย่างต่อไปนี้ใช้ตารางที่ได้รับซึ่งเป็นคำสั่ง SELECT หลังจากส่วนคำสั่ง FROM เพื่อส่งคืนค่าเก่าและใหม่สำหรับการปรับปรุงเพิ่มเติม:

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

41

การอัปเดตผ่าน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

39

หากคุณใช้ SQL Server คุณสามารถอัปเดตหนึ่งตารางจากอีกตารางหนึ่งโดยไม่ระบุการเข้าร่วมและเพียงแค่เชื่อมโยงทั้งสองจากส่วนwhereคำสั่ง สิ่งนี้ทำให้แบบสอบถาม SQL ง่ายขึ้นมาก:

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

25

รวมวิธีการต่าง ๆ ทั้งหมดไว้ที่นี่

  1. เลือกอัพเดต
  2. อัพเดตด้วยนิพจน์ตารางทั่วไป
  3. ผสาน

โครงสร้างตารางตัวอย่างอยู่ด้านล่างและจะอัปเดตจาก Product_BAK เป็นตารางผลิตภัณฑ์

สินค้า

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

23

วิธีอื่นคือใช้ตารางที่ได้รับ:

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

23
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

22

แม้จะมีวิธีการที่สั้นกว่าและอาจทำให้คุณประหลาดใจ:

ชุดข้อมูลตัวอย่าง:

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

1
ใช่ - ไม่มีการเข้าร่วมโดยไม่มีวัตถุประสงค์และไม่ - สิ่งนี้ไม่สามารถใช้กับตัวแปรตารางได้
Bartosz X

1
ฉันคิดว่าถ้าคุณใช้ [_id] ใน #SOURCE ของคุณไม่ใช่ [ID] เหมือนกับ # DESTINATION คุณอาจปล่อยให้คุณเข้าร่วม "on # DESTINATION.ID = # SOURCE._id หรือใช้ตัวแปรตารางเช่น @tbl," บน PermTable.ID=@memorytbl._id "คุณเคยลองใช้โทรศัพท์เพื่อตอบคำถามนี้หรือไม่ .
Jenna Leaf

2
สิ่งนี้เกี่ยวข้องกับการอัพเดตจาก SELECT
Martin Smith

2
นี่เป็นแนวคิดเดียวกัน แต่เป็นวิธีการอื่น - คุณไม่จำเป็นต้องใส่ "select" เลยเพื่อให้ได้ JOIN และ WHERE ในคำสั่ง update - ซึ่งเป็นประเภทของการสืบค้น SELECT โดยไม่ต้องเขียน SELECT
Bartosz X

19

ใช้:

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

14

ในคำตอบที่ยอมรับหลังจาก:

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

ฉันจะเพิ่ม:

OUTPUT deleted.*, inserted.*

สิ่งที่ฉันมักจะทำคือการใส่ทุกอย่างในธุรกรรมที่มีการสำรองข้อมูลและใช้"OUTPUT": ด้วยวิธีนี้ฉันเห็นทุกสิ่งที่กำลังจะเกิดขึ้น เมื่อฉันมีความสุขกับสิ่งที่ฉันเห็นฉันเปลี่ยนROLLBACKเป็นCOMMITเข้าไป

ฉันมักจะต้องจัดทำเอกสารสิ่งที่ฉันทำดังนั้นฉันจึงใช้"results to Text"ตัวเลือกเมื่อฉันเรียกใช้แบบสอบถามแบบย้อนกลับและฉันบันทึกทั้งสคริปต์และผลลัพธ์ของผลลัพธ์ (แน่นอนว่ามันไม่เป็นประโยชน์ถ้าฉันเปลี่ยนแถวมากเกินไป)


12
UPDATE table AS a
INNER JOIN table2 AS b
ON a.col1 = b.col1
INNER JOIN ... AS ...
ON ... = ...
SET ...
WHERE ...

2
รูปแบบนี้เป็นสิ่งที่ทำงานใน MS Access การวาง JOIN ไว้ท้ายจะได้รับข้อความ "ข้อผิดพลาดทางไวยากรณ์ (ตัวดำเนินการหายไป)" ตัวอย่างเพิ่มเติมได้ที่นี่: fmsinc.com/microsoftaccess/query/snytax/update-query.html
travis

12

โซลูชันด้านล่างใช้ได้กับฐานข้อมูล MySQL:

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

12

วิธีอื่นในการอัปเดตจากคำสั่งที่เลือก:

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'

5
วิธีอื่นในการอัปเดตจากคำสั่งที่เลือกแตกต่างจากคำตอบอื่น ๆ อย่างไร โปรดอธิบายคำตอบของคุณให้ละเอียด โปรดจำไว้ว่า: คำตอบที่ดีมักจะมีคำอธิบายเกี่ยวกับสิ่งที่ทำไปแล้วและทำไมมันถึงทำแบบนั้นไม่เพียง แต่สำหรับ OP แต่สำหรับผู้เยี่ยมชมในอนาคต
B001 ᛦ

คำตอบนี้ปรากฏในคิวตรวจสอบคุณภาพต่ำเนื่องจากคุณไม่ได้ให้คำอธิบายใด ๆ ของรหัส หากรหัสนี้ตอบคำถามให้พิจารณาเพิ่มการเพิ่มข้อความอธิบายรหัสในคำตอบของคุณ ด้วยวิธีนี้คุณมีแนวโน้มที่จะได้รับ upvotes มากขึ้นและช่วยให้ผู้ถามเรียนรู้สิ่งใหม่
lmo

8

ตัวเลือกที่ 1: การใช้ Inner Join:

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: แบบสอบถามย่อยที่เกี่ยวข้องร่วม

UPDATE table 
SET Col1 = B.Col1, 
    Col2 = B.Col2 
FROM (
    SELECT ID, Col1, Col2 
    FROM other_table) B
WHERE 
    B.ID = table.ID

มันเหมาะกับคุณหรือไม่ ฉันใช้ข้อความค้นหาเดียวกัน แต่มีข้อผิดพลาดเมื่อใช้การเข้าร่วมภายในนามแฝงไม่สามารถแก้ไขได้ อย่างไรก็ตามแบบสอบถามย่อยที่เกี่ยวข้องกับการทำงานอย่างสมบูรณ์
Pratyush Raizada

@PratyushRaizada คุณมีข้อผิดพลาดอะไร?
Santhana

ฉันไม่มีบันทึกข้อผิดพลาดที่แน่นอน แต่มีการอ้างอิงนามแฝง A ก่อนการมอบหมายซึ่งทำให้เกิดข้อผิดพลาด
Pratyush Raizada

ฉันใช้การสืบค้นย่อยที่สัมพันธ์กัน
pat capozzi

3
UPDATE table1
SET column1 = (SELECT expression1
               FROM table2
               WHERE conditions)
[WHERE conditions];

ไวยากรณ์สำหรับคำสั่ง UPDATE เมื่ออัพเดตหนึ่งตารางด้วยข้อมูลจากอีกตารางหนึ่งใน SQL Server


1

คุณสามารถใช้จากนี้เพื่อปรับปรุงในเซิร์ฟเวอร์ sql

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'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.