SQL DELETE ด้วย INNER JOIN


120

มี 2 ตาราง, spawnlistและและฉันต้องการที่จะลบข้อมูลจาก npc เป็นสิ่งเดียวที่ "เชื่อมต่อ" ตาราง ฉันได้ลองใช้สคริปต์นี้แล้ว แต่ไม่ได้ผลspawnlsitnpc_templateid = n.idTemplate

ฉันได้ลองสิ่งนี้แล้ว:

DELETE s FROM spawnlist s
INNER JOIN npc n ON s.npc_templateid = n.idTemplate
WHERE (n.type = "monster");

1
รู้สึกประหลาดใจมากขึ้นเพราะโดยทั่วไปแล้วชุมชน L2 จะรักษาตัวเอง แปลกนิดหน่อยที่อ่านคำถามแล้วคิดว่า "ดูเหมือน ... อืม ... มัน!" :)
Corbin

1
@ Corbin ฉันเข้าใจว่าคุณหมายถึงอะไร น่าสนใจพอฉันได้รับความช่วยเหลือเกี่ยวกับคำถาม L2 สำหรับโครงการงาน
Marco Aurélio Deleu

ลบออกจาก table1 จาก table1 t1 inner join table2 t2 บน t1.id = t2.id; ในรายละเอียดyoutu.be/_tyUVrS2iH4
Amresh Kumar Singh

คำตอบ:


225

เพิ่ม.*ไปsในบรรทัดแรกของคุณ

ลอง:

DELETE s.* FROM spawnlist s
INNER JOIN npc n ON s.npc_templateid = n.idTemplate
WHERE (n.type = "monster");

นี่คือข้อผิดพลาดที่ฉันได้รับ: [Err] 1064 - คุณมีข้อผิดพลาดในไวยากรณ์ SQL ของคุณ ตรวจสอบคู่มือที่สอดคล้องกับเวอร์ชันเซิร์ฟเวอร์ MySQL ของคุณสำหรับไวยากรณ์ที่ถูกต้องเพื่อใช้ใกล้ 'spawnlist FROM db.root.spawnlist s INNER JOIN db.root.npc n ON s.npc_t' ที่บรรทัด 1 [Err] DELETE l2revo.root spawnlist จาก db.root.spawnlist s INNER JOIN db.root.npc n ON s.npc_templateid = n.idTemplate WHERE (n.type = "monster"); [ข่าวสาร] จบแล้ว - ไม่สำเร็จ -------------------------------------------- ------
JoinOG

spawnlistในข้อผิดพลาดของคุณดูเหมือนว่าคุณกำลังใช้สองชื่อแตกต่างกันสำหรับเซิร์ฟเวอร์ ฉันเห็นl2revo.root.spawnlistและdb.root.spawnlist.
ThinkingStiff

ฉันทำผิดพลาดในการวางที่นี่ แต่ชื่อผู้ใช้และชื่อฐานข้อมูลเหมือนกันเนื่องจากข้อผิดพลาดของฉัน
JoinOG

ลองเพิ่มASชื่อแทนของคุณ
ThinkingStiff

4
@GauravRamanan the s. * บอก mysql ว่าจะลบอะไรคุณไม่ต้องการลบแถวจากตารางที่เข้าร่วม
ก.ค.

12

หากฐานข้อมูลเป็น InnoDB คุณควรใช้คีย์ต่างประเทศและเรียงซ้อนในการลบสิ่งนี้จะทำตามที่คุณต้องการและส่งผลให้ไม่มีการจัดเก็บข้อมูลซ้ำซ้อน

สำหรับตัวอย่างนี้ฉันไม่คิดว่าคุณต้องการสิ่งแรก:

DELETE s 
FROM spawnlist AS s 
INNER JOIN npc AS n ON s.npc_templateid = n.idTemplate 
WHERE n.type = "monster";

อาจเป็นความคิดที่ดีกว่าในการเลือกแถวก่อนลบเพื่อให้แน่ใจว่าคุณได้ลบสิ่งที่คุณต้องการ:

SELECT * FROM spawnlist
INNER JOIN npc ON spawnlist.npc_templateid = npc.idTemplate
WHERE npc.type = "monster";

คุณสามารถตรวจสอบไวยากรณ์การลบ MySQL ได้ที่นี่: http://dev.mysql.com/doc/refman/5.0/en/delete.html


นี่คือข้อผิดพลาดที่ฉันได้รับ: [Err] 1064 - คุณมีข้อผิดพลาดในไวยากรณ์ SQL ของคุณ ตรวจสอบคู่มือที่สอดคล้องกับเวอร์ชันเซิร์ฟเวอร์ MySQL ของคุณสำหรับไวยากรณ์ที่ถูกต้องเพื่อใช้ใกล้ 's INNER JOIN npc n ON s.npc_templateid = n.idTemplate WHERE n.type = "monste' ที่บรรทัด 1 [Err] ลบจากการวางไข่ของ INNER เข้าร่วม npc n บน s.npc_templateid = n.idTemplate WHERE n.type = "monster"; [Msg] เสร็จสิ้น - ไม่สำเร็จ ------------------------ --------------------------
JoinOG

เปลี่ยนแล้วอาจจะประสบความสำเร็จมากกว่านี้?
แดน

ข้อผิดพลาด: [Err] 1066 - ไม่ใช่ตาราง / นามแฝงที่ไม่ซ้ำกัน: 'npc' [Err] ลบรายการวางไข่จาก spawnlist, npc INNER JOIN npc WHERE spawnlist.npc_templateid = npc.idTemplate AND npc.type = "monster"; [ข่าวสาร] จบแล้ว - ไม่สำเร็จ -------------------------------------------- ------
JoinOG

หากคุณจะเรียกใช้เพียงครั้งเดียวคุณสามารถเรียกใช้สิ่งที่ไม่มีประสิทธิภาพอย่างน่ากลัว: DELETE FROM spawnlist WHERE npc_templateid IN (SELECT idTemplate จาก npc WHERE type = "monster");
Corbin

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

6

หากฐานข้อมูลเป็น InnoDB คุณไม่จำเป็นต้องทำการรวมในการลบ เท่านั้น

DELETE FROM spawnlist WHERE spawnlist.type = "monster";

สามารถใช้เพื่อลบระเบียนทั้งหมดที่เชื่อมโยงกับคีย์ต่างประเทศในตารางอื่น ๆ โดยคุณต้องเชื่อมโยงตารางของคุณก่อนในเวลาออกแบบ

CREATE TABLE IF NOT EXIST spawnlist (
  npc_templateid VARCHAR(20) NOT NULL PRIMARY KEY

)ENGINE=InnoDB;

CREATE TABLE IF NOT EXIST npc (
  idTemplate VARCHAR(20) NOT NULL,

  FOREIGN KEY (idTemplate) REFERENCES spawnlist(npc_templateid) ON DELETE CASCADE

)ENGINE=InnoDB;

หากคุณใช้ MyISAM คุณสามารถลบบันทึกการเข้าร่วมเช่นนี้ได้

DELETE a,b
FROM `spawnlist` a
JOIN `npc` b
ON a.`npc_templateid` = b.`idTemplate`
WHERE a.`type` = 'monster';

ในบรรทัดแรกฉันได้เตรียมข้อมูลเบื้องต้นของตารางชั่วคราวสองตารางสำหรับการลบเรกคอร์ดในบรรทัดที่สองฉันได้กำหนดตารางความมีอยู่ให้กับทั้ง a และ b แต่ที่นี่ฉันได้เชื่อมโยงทั้งสองตารางเข้าด้วยกันด้วยคีย์เวิร์ด join และฉันได้จับคู่คีย์หลักและคีย์ต่างประเทศแล้ว สำหรับทั้งสองตารางที่สร้างลิงก์ในบรรทัดสุดท้ายฉันได้กรองเรกคอร์ดตามฟิลด์ที่จะลบ


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