อัปเดตหรือแทรก (หลายแถวและคอลัมน์) จากแบบสอบถามย่อยใน PostgreSQL


106

ฉันกำลังพยายามทำสิ่งนี้ใน postgres:

  • UPDATE table1 SET (col1, col2) = (SELECT col2, col3 FROM othertable WHERE othertable.col1 = 123);

  • INSERT INTO table1 (col1, col2) VALUES (SELECT col1, col2 FROM othertable)

แต่จุดที่ 1 ไม่สามารถทำได้แม้จะมี postgres 9.0 ตามที่กล่าวไว้ในเอกสาร ( http://www.postgresql.org/docs/9.0/static/sql-update.html )

จุดที่ 2 ดูเหมือนจะไม่ทำงาน ฉันได้รับข้อผิดพลาดต่อไปนี้: เคียวรีย่อยต้องส่งคืนคอลัมน์เดียวเท่านั้น

หวังว่าใครบางคนจะมีวิธีแก้ปัญหาสำหรับฉัน มิฉะนั้นการสืบค้นจะใช้เวลานาน :(

FYI: ฉันกำลังพยายามเลือกคอลัมน์ต่างๆจากหลาย ๆ ตารางและจัดเก็บไว้ในตารางชั่วคราวเพื่อให้แอปพลิเคชันอื่นสามารถดึงข้อมูลที่เตรียมไว้ได้อย่างง่ายดาย

คำตอบ:


175

สำหรับ UPDATE

ใช้:

UPDATE table1 
   SET col1 = othertable.col2,
       col2 = othertable.col3 
  FROM othertable 
 WHERE othertable.col1 = 123;

สำหรับ INSERT

ใช้:

INSERT INTO table1 (col1, col2) 
SELECT col1, col2 
  FROM othertable

คุณไม่จำเป็นต้องใช้VALUESไวยากรณ์หากคุณใช้ SELECT เพื่อเติมค่า INSERT


1
เป็นไปได้หรือไม่ที่จะรวมการอัปเดตและการแทรกเพื่อที่ว่าหากล้มเหลวอีกอันจะถูกใช้โดยไม่เกิดข้อผิดพลาด (แยกกันสำหรับแต่ละแถว) ฉันคิดว่านั่นจะเป็นวิธีแก้ปัญหาที่สมบูรณ์ยิ่งขึ้นสำหรับคำถามนี้ (ตัวอย่างเช่นstackoverflow.com/a/6527838/781695 )
ผู้ใช้

26

คำตอบของ OMG Ponies ทำงานได้อย่างสมบูรณ์แบบ แต่ในกรณีที่คุณต้องการอะไรที่ซับซ้อนกว่านี้นี่คือตัวอย่างของแบบสอบถามการอัปเดตขั้นสูงเล็กน้อย:

UPDATE table1 
SET col1 = subquery.col2,
    col2 = subquery.col3 
FROM (
    SELECT t2.foo as col1, t3.bar as col2, t3.foobar as col3 
    FROM table2 t2 INNER JOIN table3 t3 ON t2.id = t3.t2_id
    WHERE t2.created_at > '2016-01-01'
) AS subquery
WHERE table1.id = subquery.col1;

1
คุณดีที่สุด :) :)
Ashwini

1
สมบูรณ์แบบ วิธีนี้ได้ผลดีที่สุดโดยคุณต้องเลือกชุดย่อยตามเงื่อนไขที่เกี่ยวข้องกับตารางที่อัปเดตเอง
mythicalcoder

@David Namenyi คุณสามารถอธิบายคำถามนี้ได้หรือไม่?
Chintan Pathak

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