วิธีการลบแถวหนึ่งจากตาราง mysql ด้วยค่าคอลัมน์เดียวกัน


153

ฉันมีปัญหากับการสืบค้นใน MySQL ตารางของฉันมี 4 คอลัมน์และดูเหมือนว่า:

id_users    id_product    quantity    date
 1              2              1       2013
 1              2              1       2013
 2              2              1       2013
 1              3              1       2013

id_usersและid_productเป็นกุญแจต่างประเทศจากตารางที่แตกต่างกัน

สิ่งที่ฉันต้องการคือการลบเพียงหนึ่งแถว:

1     2     1    2013

ซึ่งปรากฏสองครั้งดังนั้นฉันแค่ต้องการลบ

ฉันได้ลองใช้แบบสอบถามนี้:

delete from orders where id_users = 1 and id_product = 2

แต่จะลบทั้งคู่ (เนื่องจากมีการทำซ้ำ) มีคำแนะนำในการแก้ปัญหานี้หรือไม่?

คำตอบ:


208

เพิ่มlimitไปลบแบบสอบถาม

delete from orders 
where id_users = 1 and id_product = 2
limit 1

3
นี่เป็นการลบแถวเดียวเท่านั้น หากมี 3 กับผู้ใช้และรหัสผลิตภัณฑ์นี้จะมี 2
Rob

10
ใช่ OP บอกว่าเขาต้องการลบ 1 แถว นั่นคือสิ่งที่แบบสอบถามของฉันทำ
เริ่ม

2
ใช่ แต่ฉันคิดว่านี่ไม่ใช่สิ่งที่เขา / เธอต้องการ
Rob

3
ขอบคุณ Juergen นี่คือทั้งหมดที่ฉันต้องการ!
ดานี

3
สิ่งที่ OP ต้องการทำจริงๆคือตรวจสอบก่อนว่าแถวใดมีการทำซ้ำจากนั้นลบรายการที่ซ้ำกัน
wbinky

64

ตารางทั้งหมดควรมีคีย์หลัก (ประกอบด้วยคอลัมน์เดียวหรือหลายคอลัมน์) แถวที่ซ้ำกันไม่สมเหตุสมผลในฐานข้อมูลเชิงสัมพันธ์ คุณสามารถ จำกัด จำนวนแถวที่ลบได้โดยใช้LIMIT:

DELETE FROM orders WHERE id_users = 1 AND id_product = 2 LIMIT 1

แต่นั่นเป็นเพียงการแก้ไขปัญหาปัจจุบันของคุณคุณควรทำงานกับปัญหาที่ใหญ่กว่าโดยการกำหนดคีย์หลัก


1
สิ่งนี้ดีที่จะกล่าวถึงว่าคีย์หลักควรไม่ซ้ำกันในฐานข้อมูลเชิงสัมพันธ์
พอล

1
@ พอลนี่คือสิ่งที่ฉันจะพูด แต่อย่าลืมรหัสที่ไม่ซ้ำกันไม่จำเป็นต้องหมายถึงคีย์หลัก
Ryan Fung

20

คุณต้องระบุจำนวนแถวที่ควรลบ ในกรณีของคุณ (และฉันคิดว่าคุณต้องการเก็บไว้หนึ่งอันเท่านั้น) สิ่งนี้สามารถทำได้ดังนี้:

DELETE FROM your_table WHERE id_users=1 AND id_product=2
LIMIT (SELECT COUNT(*)-1 FROM your_table WHERE id_users=1 AND id_product=2)

ขอบคุณ Rob แต่ไม่ ... ฉันแค่ต้องการลบหนึ่งแถวเดียวเพื่อไม่ให้เป็นหนึ่งเดียว
Dani

สิ่งนี้ไม่ได้ผลสำหรับฉันใน 5.5.40 แต่ก็มีข้อผิดพลาดทางไวยากรณ์ ดังที่กล่าวไว้ที่นี่: stackoverflow.com/a/578926/1076075ดูเหมือนว่าเราไม่สามารถใช้แบบสอบถามย่อยเพื่อระบุค่าของอนุประโยค LIMIT สำหรับใครก็ตามที่พยายามทำสิ่งนี้ด้วยวิธีนี้ลองดู: stackoverflow.com/q/578867/1076075
Bharadwaj Srigiriraju

8

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


1
หรือแถวถาวร ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันควรพูด รหัสจะถูกใช้สำหรับสถานการณ์ประเภทนี้ หากคุณกังวลเรื่องพื้นที่: BIGINT มีขนาดเพียง 8 ไบต์!
Ismael Miguel

5

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

ฉันจะให้วิธีอื่น:

  1. โดยการสร้างดัชนีที่ไม่ซ้ำ

ฉันเห็น id_users และ id_product ควรไม่ซ้ำกันในตัวอย่างของคุณ

ALTER IGNORE TABLE orders ADD UNIQUE INDEX unique_columns_index (id_users, id_product)

สิ่งเหล่านี้จะลบแถวที่ซ้ำกันด้วยข้อมูลเดียวกัน

แต่ถ้าคุณยังคงได้รับข้อผิดพลาดแม้ว่าคุณจะใช้ IGNORE clause ให้ลองทำดังนี้:

ALTER TABLE orders ENGINE MyISAM;
ALTER IGNORE TABLE orders ADD UNIQUE INDEX unique_columns_index (id_users, id_product)
ALTER TABLE orders ENGINE InnoDB; 
  1. โดยการสร้างตารางอีกครั้ง

หากมีหลายแถวที่มีค่าซ้ำกันคุณสามารถสร้างตารางใหม่ได้

RENAME TABLE `orders` TO `orders2`;

CREATE TABLE `orders` 
SELECT * FROM `orders2` GROUP BY id_users, id_product;

1

คุณต้องเพิ่มรหัสที่เพิ่มขึ้นอัตโนมัติสำหรับแต่ละแถวหลังจากนั้นคุณสามารถลบแถวด้วยรหัสได้ ดังนั้นตารางของคุณจะมีรหัสเฉพาะสำหรับแต่ละแถวและ id_user, id_product ecc ...

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