Aynı sütun değerlerine sahip mysql tablosundan belirli bir satırı nasıl silebilirim?


153

MySQL'deki sorgularımla ilgili bir sorunum var. Masamın 4 sütunu var ve şöyle görünüyor:

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

id_usersve id_productfarklı tablolardan yabancı anahtarlar.

İstediğim sadece bir satırı silmek:

1     2     1    2013

Hangi iki kez görünür, bu yüzden sadece silmek istiyorum.

Bu sorguyu denedim:

delete from orders where id_users = 1 and id_product = 2

Ancak her ikisini de silecektir (çoğaltıldıkları için). Bu sorunu çözmeyle ilgili ipuçları var mı?

Yanıtlar:


208

Bir ekleme limitiçin silme sorgusu

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

3
Bu yalnızca bir satırı siler. Bu kullanıcı ve ürün kimliği ile 3 olsaydı, 2 kalırdı.
— Rob

10
Evet, OP 1 satırı silmek istediğini söylüyor. Benim sorgu bu yapar.
— juergen d

2
Evet, ama bence istediği bu değil.
— Rob

3
Teşekkür ederim Juergen. Tüm ihtiyacım olan bu!
— Dani

3
OP'nin gerçekten yapması gereken, önce hangi satırların çoğaltıldığını kontrol etmek ve daha sonra çoğaltmaları silmek.
— wbinky

64

Tüm tabloların birincil anahtarı (tek veya birden çok sütundan oluşur) olmalıdır, yinelenen satırlar ilişkisel veritabanında anlamlı değildir. LIMITBununla birlikte , silme satırlarının sayısını sınırlayabilirsiniz :

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

Ancak bu sadece mevcut sorununuzu çözüyor, birincil anahtarları tanımlayarak kesinlikle daha büyük sorun üzerinde çalışmalısınız.


1
Bu, birincil anahtarın ilişkisel bir veritabanında benzersiz olması gerektiğini belirtmek iyidir.
— Paul

1
@Paul Tam olarak söyleyeceğim şey bu. Ancak benzersiz anahtarı unutma, birincil anahtar anlamına gelmez.
— Ryan Fung

20

Silinecek satır sayısını belirtmeniz gerekir. Sizin durumunuzda (ve ben sadece bir tane tutmak istediğinizi varsayalım) bu böyle yapılabilir:

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)

Teşekkür ederim Rob, ama hayır ... Ben sadece bir satır silmek değil, sadece bir satır silmek istiyorum
— Dani

Bu 5.5.40 benim için çalışmıyor, bir sözdizimi hatası atar. Burada belirtildiği gibi: stackoverflow.com/a/578926/1076075 , bir LIMIT deyiminin değerini belirtmek için bir alt sorgu kullanamayacağımız anlaşılıyor. Bu şekilde bir şeyler yapmaya çalışan herkes için şunu kontrol edin: stackoverflow.com/q/578867/1076075
— Bharadwaj Srigiriraju

8

Tablo tasarlamanın en iyi yolu, otomatik artış olarak bir geçici satır eklemek ve birincil anahtar olarak tutmaktır. Böylece yukarıdaki sorunlardan kaçınabiliriz.


1
Veya kalıcı bir sıra. Bunun eski bir soru olduğunu biliyorum, ama söylemeliyim. Kimlikler bu tür bir durum için kullanılır. Alandan endişe ediyorsanız: BİR BÜYÜK sadece 8 bayttır!
— Ismael Miguel

5

Satır silme için zaten yanıtlar var LIMIT. İdeal olarak, tablonuzda birincil anahtar olmalıdır. Ama yoksa.

Başka yollar vereceğim:

  1. Benzersiz dizin oluşturarak

Örnekte id_users ve id_product işlevlerinin benzersiz olması gerektiğini görüyorum.

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

Bunlar, aynı verilere sahip yinelenen satırları silecektir.

Ancak yine de hata alıyorsanız, IGNORE yantümcesini kullansanız bile şunu deneyin:

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. Tekrar tablo oluşturarak

Yinelenen değerleri olan birden çok satır varsa, tabloyu da yeniden oluşturabilirsiniz

RENAME TABLE `orders` TO `orders2`;

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

1

Her satır için otomatik olarak artan bir kimlik eklemeniz gerekir, bundan sonra satırı kimliğiyle silebilirsiniz. tablonuzun her satır için benzersiz bir kimliği olacak ve id_user, id_product ecc ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.