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.