SQL UPDATE SET หนึ่งคอลัมน์จะเท่ากับค่าในตารางที่เกี่ยวข้องซึ่งอ้างอิงโดยคอลัมน์อื่น?


112

ฉันหวังว่ามันจะสมเหตุสมผลให้ฉันอธิบายเพิ่มเติม:

มีตารางข้อมูลการติดตามของโปรแกรมตอบคำถามที่แต่ละแถวมี ..

รหัสคำถามและรหัสคำตอบ (มีตารางสำหรับแต่ละตาราง) ดังนั้นเนื่องจากข้อผิดพลาดจึงมีรหัสคำถามจำนวนมากที่ตั้งค่าเป็น NULL แต่รหัสคำถามของรหัสคำตอบที่เกี่ยวข้องอยู่ในตารางคำตอบ

ดังนั้นให้บอกว่า QuestionID เป็น NULL และ AnswerID คือ 500 ถ้าเราไปที่ตาราง Answers และค้นหา AnswerID 500 จะมีคอลัมน์ที่มีรหัสคำถามที่ควรจะเป็นตำแหน่งที่ค่า NULL อยู่

โดยพื้นฐานแล้วฉันต้องการตั้งค่า NULL QuestionID แต่ละรายการให้เท่ากับรหัสคำถามที่พบในตารางคำตอบในแถวคำตอบของรหัสคำตอบที่อยู่ในตารางการติดตาม (แถวเดียวกับรหัสคำถาม NULL ที่กำลังเขียน)

ฉันจะทำอย่างไร

UPDATE QuestionTrackings
SET QuestionID = (need some select query that will get the QuestionID from the AnswerID in this row)
WHERE QuestionID is NULL AND ... ?

ไม่แน่ใจว่าฉันจะสามารถกำหนดรหัสคำถามให้กับรหัสคำถามจากรหัสคำตอบที่ตรงกันได้อย่างไร ...


MySQL และ Microsoft SQL Server แต่ละตัวสนับสนุนส่วนขยายของไวยากรณ์ SQL เพื่อรองรับการอัปเดตหลายตาราง ยี่ห้ออื่นไม่ทำ คุณยังไม่ได้บอกว่าคุณใช้ฐานข้อมูลยี่ห้ออะไร
Bill Karwin

คำตอบ:


171
update q
set q.QuestionID = a.QuestionID
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

ฉันแนะนำให้ตรวจสอบว่าผลลัพธ์ที่กำหนดให้อัปเดตคืออะไรก่อนที่จะรันการอัปเดต (แบบสอบถามเดียวกันเพียงแค่เลือก)

select *
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

โดยเฉพาะอย่างยิ่งว่าแต่ละรหัสคำตอบมีเพียง 1 รหัสคำถามที่เกี่ยวข้องหรือไม่


7
ฉันไม่แน่ใจว่าทำไม แต่สิ่งนี้ไม่ได้ผลสำหรับฉัน แต่สิ่งนี้: update QuestionTrackings q inner join QuestionAnswers a on q.AnswerID = a.AnswerID set q.QuestionID = a.QuestionID; ดูเหมือนว่าจะเป็นแบบสอบถามพื้นฐานเดียวกันในลำดับที่ต่างกัน ทำไม?
billynoah

2
@billynoah, ORA-00971: ไม่มีคีย์เวิร์ด SET ใน Oracle
masT

2
มีปัญหากับสถานการณ์ที่คล้ายกันใน PhpMyAdmin ผ่าน MySQL ในกรณีของฉันคอลัมน์ต้นทางและปลายทางอยู่ในตารางเดียวกัน แต่การเลือกเรกคอร์ดจะขึ้นอยู่กับตารางอื่น แบบสอบถามรุ่น "SELECT" ใช้งานได้ แต่คำสั่ง UPDTATE แสดงข้อผิดพลาดทางไวยากรณ์ที่ "FROM"
2NinerRomeo

3
ฉันแก้ไขปัญหาได้โดยการกำจัด "FROM" ซึ่งดูเหมือนมากกว่านี้:UPDATE table1 NATURAL JOIN table2 SET table1.col1 = table1.col2 WHERE table2.col3 ="condition"
2NinerRomeo

คือ "q" จาก "update q" ในคำตอบพารามิเตอร์การสืบค้นตามตัวอักษรหรือเป็นเพียงชวเลขของคุณสำหรับชื่อตาราง
Shawn

28

หากไม่มีสัญกรณ์ update-and-join (ไม่ใช่ DBMS ทั้งหมดที่รองรับ) ให้ใช้:

UPDATE QuestionTrackings
   SET QuestionID = (SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
   WHERE QuestionID IS NULL
     AND EXISTS(SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)

บ่อยครั้งในข้อความค้นหาเช่นนี้คุณต้องกำหนดคุณสมบัติของคำสั่ง WHERE ด้วยส่วนคำสั่ง EXISTS ที่มีแบบสอบถามย่อย สิ่งนี้จะป้องกันไม่ให้ UPDATE เหยียบย่ำแถวที่ไม่มีการจับคู่ (โดยปกติจะลบค่าทั้งหมด) ในกรณีนี้เนื่องจากรหัสคำถามที่ขาดหายไปจะเปลี่ยน NULL เป็น NULL เนื้อหาจึงไม่สำคัญ


วิธีนี้ใช้ได้ผลสำหรับฉันบน Oracle 12c (ซึ่งวิธีการเข้าร่วมการอัปเดตล้มเหลว)
shwartz

16

ฉันไม่รู้ว่าคุณประสบปัญหาเดียวกันกับฉันบน MySQL Workbench หรือไม่ แต่การเรียกใช้แบบสอบถามโดยINNER JOINใช้FROMคำสั่งafter ไม่ได้ผลสำหรับฉัน ฉันไม่สามารถเรียกใช้แบบสอบถามได้เนื่องจากโปรแกรมบ่นเกี่ยวกับFROMคำสั่ง

ดังนั้นเพื่อให้แบบสอบถามใช้งานได้ฉันจึงเปลี่ยนเป็น

UPDATE table1 INNER JOIN table2 on table1.column1 = table2.column1
SET table1.column2 = table2.column4
WHERE table1.column3 = 'randomCondition';

แทน

UPDATE a
FROM table1 a INNER JOIN table2 b on a.column1 = b.column1
SET a.column2 = b.column4
WHERE a.column3 = 'randomCondition';

ฉันเดาว่าโซลูชันของฉันเป็นไวยากรณ์ที่ถูกต้องสำหรับ MySQL


ใช่ดูเหมือนสำหรับ Mysql JOIN ถือเป็นส่วนหนึ่งของส่วน "table_references" ของแบบสอบถาม MySQL Join
AWP


7

ฉันมีคำถามเดียวกัน นี่คือวิธีแก้ปัญหาที่ใช้งานได้ซึ่งคล้ายกับของ eglasius ฉันใช้ postgresql

UPDATE QuestionTrackings
SET QuestionID = a.QuestionID
FROM QuestionTrackings q, QuestionAnswers a
WHERE q.QuestionID IS NULL

มันบ่นว่าถ้าใช้ q แทนชื่อตารางในบรรทัดที่ 1 และไม่ควรนำหน้า QuestionID ในบรรทัดที่ 2


3
 select p.post_title,m.meta_value sale_price ,n.meta_value   regular_price
    from  wp_postmeta m 
    inner join wp_postmeta n
      on m.post_id  = n.post_id
    inner join wp_posts p
      ON m.post_id=p.id 
    and m.meta_key = '_sale_price'
    and  n.meta_key = '_regular_price'
     AND p.post_type = 'product';



 update  wp_postmeta m 
inner join wp_postmeta n
  on m.post_id  = n.post_id
inner join wp_posts p
  ON m.post_id=p.id 
and m.meta_key = '_sale_price'
and  n.meta_key = '_regular_price'
 AND p.post_type = 'product'
 set m.meta_value = n.meta_value;


1

อัปเดตข้อมูลตารางที่ 2 ในตารางที่ 1 จำเป็นต้องเข้าร่วมภายในก่อน SET:

`UPDATE `table1` INNER JOIN `table2` ON `table2`.`id`=`table1`.`id` SET `table1`.`name`=`table2`.`name`, `table1`.`template`=`table2`.`template`;

1

ด้านล่างใช้งานได้กับ mysql

update table1 INNER JOIN table2 on table1.col1 =  table2.col1
set table1.col1 =  table2.col2

0

ฉันคิดว่ามันน่าจะใช้ได้

UPDATE QuestionTrackings
SET QuestionID = (SELECT QuestionID
                  FROM AnswerTrackings
                  WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
WHERE QuestionID IS NULL
AND AnswerID IS NOT NULL;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.