วิธีการทำ 3 ตารางเข้าร่วมในการสืบค้น UPDATE?


466

ฉันถามคำถามและได้รับคำตอบที่ช่วยได้

   UPDATE TABLE_A a JOIN TABLE_B b 
   ON a.join_col = b.join_col AND a.column_a = b.column_b 
   SET a.column_c = a.column_c + 1

ตอนนี้ฉันกำลังมองหาที่จะทำถ้ามี 3 ตารางที่เกี่ยวข้องกับสิ่งนี้

    UPDATE tableC c JOIN tableB b JOIN tableA a

คำถามของฉันเป็นพื้น ... เป็นไปได้ที่จะเข้าร่วม 3 ตารางในUPDATEงบ? และไวยากรณ์ที่ถูกต้องสำหรับมันคืออะไร? ขอบคุณ. ฉันจะทำ ...

 JOIN tableB, tableA
 JOIN tableB JOIN tableA

2
แน่นอนว่าเป็นไปได้ ให้มันลอง. ไวยากรณ์เป็นเหมือนที่คุณมี - คุณเพียงแค่ต้องเพิ่มต่อไปJOINและONสภาพของมันเช่นเดียวกับที่คุณต้องการในSELECTแบบสอบถาม
Michael Berkowski

2
UPDATE t1 JOIN t2 ON t1.id = t2.t1_id JOIN t3 ON t3.id = t2.t3_id SET t1.col = 'newval'
Michael Berkowski

1
คำถามที่กล่าวถึงอยู่ที่นี่: stackoverflow.com/questions/15206746/…
Urs

คำตอบ:


809

คำตอบคือyesคุณสามารถ

ลองแบบนั้น

UPDATE TABLE_A a 
    JOIN TABLE_B b ON a.join_col = b.join_col AND a.column_a = b.column_b 
    JOIN TABLE_C c ON [condition]
SET a.column_c = a.column_c + 1

แก้ไข:

สำหรับการอัพเดททั่วไปเข้าร่วม:

   UPDATE TABLEA a 
   JOIN TABLEB b ON a.join_colA = b.join_colB  
   SET a.columnToUpdate = [something]

2
อย่างไรก็ตามสิ่งที่แปลกคือซอฟต์แวร์ HeidiSQL ของฉันรายงานแถวที่ได้รับผลกระทบเป็นศูนย์ถึงแม้ว่าข้อมูลจะแสดงว่ามีการอัพเดต
Pianoman

1
@Pianoman สำหรับฉันมันก็เกิดขึ้นเช่นกันและมันมีบางอย่างเกี่ยวกับ ON UPDATE CURRENT_TIMESTAMP ฉันเพิ่งเพิ่มการอัปเดตด้วยตนเองและแก้ไขมันโดยบอกว่ามันเกิดขึ้นกับคนอื่นหรือไม่
eric.itzhak

หากคุณต้องการความช่วยเหลือด้านภาพเพื่อให้การเข้าร่วมของคุณถูกต้อง: Browse-tutorials.com/tutorial/mysql-joins-visual-representation
ram4nd

ฉันคิดว่าต่อไปนี้เป็นแผนทั่วไปที่ดีกว่า: UPDATE table A JOIN table B ON {join data} JOIN table C ON {join data} JOIN {more join tables} SET A.column = {expression}(โปรดยกโทษให้ฉันหากบรรณาธิการที่เสียหายนี้จะไม่ให้ฉันขึ้นบรรทัดใหม่โดยไม่ต้องโพสต์แบบเต็ม)
UncaAlby

อยู่ไหนWHERE?? หรือWHEREเป็นไปไม่ได้?
กรีน

42

ทางเลือกในการบรรลุผลลัพธ์เดียวกันคือไม่ใช้JOINคำหลัก

UPDATE TABLE_A, TABLE_B
SET TABLE_A.column_c = TABLE_B.column_c + 1
WHERE TABLE_A.join_col = TABLE_B.join_col

3
ฉันลองสิ่งนี้ใน 5.5.62 และ mysql ไม่ชอบไวยากรณ์ ตามคู่มือ [ dev.mysql.com/doc/refman/5.6/en/update.html]ข้อความค้นหาควรเป็น:UPDATE TABLE_A, TABLE_B SET TABLE_A.column_c = TABLE_A.column_c +1 WHERE TABLE_A.join_col = TABLE_B.join_col
Noe Nieto

7
นี้ไม่นัยJOINในทางเดียวกันทำSELECT * FROM TABLE_A, TABLE_B ...ไม่
Madbreaks

ดังนั้นหมายความว่าใน 5.5 เท่านั้นที่รวมรูปแบบเข้าร่วมโดยนัยเป็นที่ยอมรับสำหรับการปรับปรุง?
userfuser

@userfuser ไม่ไม่คู่มือจะระบุไวยากรณ์: UPDATE [LOW_PRIORITY] [IGNORE] table_references SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... [WHERE where_condition]ต่อมาระบุด้วยตนเอง: "ส่วนtable_referencesคำสั่งแสดงรายการตารางที่เกี่ยวข้องในการเข้าร่วมไวยากรณ์อธิบายไว้ในหัวข้อ 13.2.9.2, ไวยากรณ์ JOIN "
hmundt

4
ไม่ใช่ผลลัพธ์ที่เหมือนกันทุกประการ - คุณสามารถรวมซ้ายกับไวยากรณ์การรวมได้
เจอราร์ดโอนีล

10

ด้านล่างนี้เป็นข้อความค้นหาอัปเดตซึ่งรวมถึงJOIN& WHEREทั้งสองอย่าง เช่นเดียวกับที่เราสามารถใช้การเข้าร่วมหลายครั้ง / ข้อที่หวังว่ามันจะช่วยให้คุณ: -

UPDATE opportunities_cstm oc JOIN opportunities o ON oc.id_c = o.id
 SET oc.forecast_stage_c = 'APX'
 WHERE o.deleted = 0
   AND o.sales_stage IN('ABC','PQR','XYZ')

3
ยินดีต้อนรับสู่ Stack Overflow! ขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือได้ทันที คำอธิบายที่เหมาะสมจะช่วยเพิ่มมูลค่าทางการศึกษาอย่างมากโดยแสดงให้เห็นว่าทำไมนี่จึงเป็นทางออกที่ดีสำหรับปัญหาและจะทำให้มีประโยชน์มากขึ้นสำหรับผู้อ่านในอนาคตที่มีคำถามคล้ายกัน แต่ไม่เหมือนกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายและระบุข้อ จำกัด และสมมติฐานที่ใช้
Toby Speight

2

แผนทั่วไปทางเลือกซึ่งฉันเพิ่งเพิ่มเป็นคำตอบอิสระเนื่องจาก "ความคิดเห็นเกี่ยวกับคำตอบ" ที่เสียหายนั้นจะไม่ขึ้นบรรทัดใหม่โดยไม่โพสต์การแก้ไขทั้งหมดแม้ว่าจะยังไม่เสร็จก็ตาม

UPDATE table A
JOIN table B ON {join fields}
JOIN table C ON {join fields}
JOIN {as many tables as you need}
SET A.column = {expression}

ตัวอย่าง:

UPDATE person P
JOIN address A ON P.home_address_id = A.id
JOIN city C ON A.city_id = C.id
SET P.home_zip = C.zipcode;

1

สำหรับตัวอย่าง PostgreSQL:

UPDATE TableA AS a
SET param_from_table_a=FALSE -- param FROM TableA
FROM TableB AS b
WHERE b.id=a.param_id AND a.amount <> 0; 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.