ลบแถวที่ไม่ได้อ้างอิงในตารางอื่น


15

ฉันมีสองตารางในฐานข้อมูล PostgreSQL 9.3 ตารางที่link_replyมีคีย์ต่างประเทศชื่อชี้ไปที่โต๊ะwhich_grouplink_group

ฉันต้องการลบแถวทั้งหมดจากlink_groupที่ไม่มีแถวที่เกี่ยวข้องlink_replyอยู่ ฟังดูธรรมดาพอ แต่ฉันก็ดิ้นรนกับมัน

มันจะเป็นอะไรที่เรียบง่ายแบบนี้ (ไม่ทำงาน)?

DELETE FROM link_group WHERE link_reply = NULL;

คุณมี DDL ให้ทุกคนดูหรือไม่?
dizzystar

ดูที่ผู้ประกอบการลบ คุณต้องระบุฟิลด์ใน links_reply
Vérace

DELETE FROM links_group USING links_group AS lg LEFT JOIN links_reply AS lr ON lg.col= lr.some_other_col WHERE links_reply.some_other_col IS NULL
หมดเวลา

ฉันมีคำถามที่คล้ายกันซึ่งใช้เวลาเห็นพ้องด้วย ดูdba.stackexchange.com/questions/251875
pbillen

คำตอบ:


19

การอ้างอิงคู่มือ:

มีสองวิธีในการลบแถวในตารางโดยใช้ข้อมูลที่มีอยู่ในตารางอื่น ๆ ในฐานข้อมูลที่มี: ใช้ย่อยเลือกหรือระบุตารางเพิ่มเติมในUSINGข้อ เทคนิคใดที่เหมาะสมกว่านั้นขึ้นอยู่กับสถานการณ์เฉพาะ

เหมืองเน้นหนัก การใช้ข้อมูลที่ไม่ได้อยู่ในตารางอื่นนั้นค่อนข้างยุ่งยาก แต่ก็มีวิธีแก้ปัญหาที่ง่าย จากคลังแสงของเทคนิคมาตรฐานถึง ...

... การNOT EXISTSต่อต้านการเข้าร่วมกึ่งน่าจะง่ายและมีประสิทธิภาพมากที่สุดสำหรับDELETE:

DELETE FROM link_group lg
WHERE  NOT EXISTS (
   SELECT FROM link_reply lr
   WHERE  lr.which_group = lg.link_group_id
   );

สมมติว่า (ตั้งแต่คำจำกัดความของตารางจะไม่ให้) เป็นชื่อคอลัมน์คีย์หลักของlink_group_idlink_group

เทคนิค@Mihai แสดงความคิดเห็นทำงานเช่นกัน (นำไปใช้อย่างถูกต้อง):

DELETE FROM link_group lg
USING  link_group      lg1
LEFT   JOIN link_reply lr ON lr.which_group = lg1.link_group_id
WHERE  lg1.link_group_id = lg.link_group_id
AND    lr.which_group IS NULL;

แต่เนื่องจากการแสดงออกของตารางในUSINGข้อผูกพันกับตารางเป้าหมาย ( lgในตัวอย่าง) กับCROSS JOINคุณจะต้องเป็นตัวอย่างของตารางเดียวกันอีกก้าวหิน ( lg1ในตัวอย่าง) สำหรับLEFT JOINซึ่งเป็นสง่าน้อยและมักจะช้าลง

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