จะลบจากการเลือกใน MySQL ได้อย่างไร?


87

รหัสนี้ใช้ไม่ได้กับ MySQL 5.0 วิธีการเขียนใหม่เพื่อให้ใช้งานได้

DELETE FROM posts where id=(SELECT id FROM posts GROUP BY id  HAVING ( COUNT(id) > 1 ))

ฉันต้องการลบคอลัมน์ที่ไม่มีรหัสเฉพาะ ฉันจะเพิ่มว่าส่วนใหญ่แล้วมันมีเพียง id เดียว (ฉันลองใช้ไวยากรณ์แล้วมันก็ใช้ไม่ได้เช่นกัน)

คำตอบ:


217

SELECT(ย่อย) สอบถามผลการกลับมาชุด ดังนั้นคุณต้องใช้INไม่ใช่=ในไฟล์WHEREประโยค

นอกจากนี้ดังที่แสดงในคำตอบนี้คุณไม่สามารถแก้ไขตารางเดียวกันจากการสืบค้นย่อยภายในแบบสอบถามเดียวกันได้ อย่างไรก็ตามคุณสามารถSELECTแล้วDELETEในคำสั่งแยกต่างหากหรือรังแบบสอบถามย่อยอื่นและนามแฝงผลแบบสอบถามย่อยภายใน (ลักษณะค่อนข้าง hacky แม้ว่า):

DELETE FROM posts WHERE id IN (
    SELECT * FROM (
        SELECT id FROM posts GROUP BY id HAVING ( COUNT(id) > 1 )
    ) AS p
)

หรือใช้การรวมตามที่ Mchlแนะนำ


1
ฉันมีโต๊ะที่มีคีย์ซ้ำกัน 150 อัน ฉันดำเนินการค้นหาข้างต้นและมีข้อความว่า "144 แถวได้รับผลกระทบ" แต่ยังคงมีคีย์ที่ซ้ำกันอยู่ ดังนั้นฉันจึงดำเนินการค้นหาอีกครั้งและมันบอกว่า 5 แถวได้รับผลกระทบอีกครั้ง: 1 แถวได้รับผลกระทบ จากนั้นคีย์ที่ซ้ำกันทั้งหมดหายไปไหน ทำไมถึงเป็นแบบนี้?
Alex

สิ่งนี้เกิดขึ้นเนื่องจากคุณกำลังลบ 1 รายการจากรายการที่ซ้ำกันแต่ละชุด:SELECT id FROM posts GROUP BY id HAVING ( COUNT(id) > 1 )
havvg

# 1248 - ทุกตารางที่ได้มาต้องมีนามแฝงของตัวเอง
Thang

@thang: นี่คือเหตุผลที่ฉันพูดกับนามแฝงการสืบค้นย่อยภายใน
BoltClock

1
คุณช่วยอธิบายว่า "As p" ทำอะไรได้บ้าง?
คริกเก็ต

22
DELETE 
  p1
  FROM posts AS p1 
CROSS JOIN (
  SELECT ID FROM posts GROUP BY id HAVING COUNT(id) > 1
) AS p2
USING (id)

ดูเหมือนจะใช้งานได้ แต่ฉันสับสนกับไวยากรณ์และไม่สามารถหาแหล่งข้อมูลจากที่อื่นเพื่ออธิบายได้ CROSS JOINเห็นได้ชัดว่าทำการรวมคาร์ทีเซียนดังนั้นดูเหมือนว่านี่อาจเป็นการทำงานที่ไม่จำเป็นหรือดำเนินการในแง่ดี ใครช่วยอธิบาย
wintron

จะทำผลิตภัณฑ์คาร์ทีเซียนก็ต่อเมื่อไม่มีUSINGข้อ เนื่องจากUSINGผลิตภัณฑ์ถูก จำกัด ไว้ที่คู่ที่มีค่าเดียวกันในidคอลัมน์ดังนั้นในความเป็นจริงจึงมีข้อ จำกัด มาก
Mchl

คุณสามารถทำสิ่งเดียวกันกับการเข้าร่วมภายในได้หรือไม่? IEDELETE p1 FROM posts AS p1 INNER JOIN ( SELECT ID FROM posts GROUP BY id HAVING COUNT(id) > 1 ) AS p2 ON p2.ID=p1.ID
Kodos Johnson

1
@ แอนดรูว์: ใช่ ฟังก์ชันการรวมเหล่านี้เหมือนกันทุกประการ
Mchl

6

คุณสามารถใช้การเข้าร่วมภายใน:

DELETE 
    ps 
FROM 
    posts ps INNER JOIN 
         (SELECT 
           distinct id 
         FROM 
             posts 
         GROUP BY id  
      HAVING COUNT(id) > 1 ) dubids on dubids.id = ps.id  

0

หากคุณต้องการลบรายการที่ซ้ำกันทั้งหมด แต่ออกจากรายการที่ซ้ำกันหนึ่งชุดนี่เป็นวิธีแก้ปัญหาหนึ่ง:

DELETE posts
FROM posts
LEFT JOIN (
    SELECT id
    FROM posts
    GROUP BY id
    HAVING COUNT(id) = 1

    UNION

    SELECT id
    FROM posts
    GROUP BY id
    HAVING COUNT(id) != 1
) AS duplicate USING (id)
WHERE duplicate.id IS NULL;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.