2013-08-22 16 views
130

Mam problem z moimi zapytaniami w MySQL. Moja tabela ma 4 kolumny i wygląda to mniej więcej tak:Jak usunąć określony wiersz z tabeli mysql z tymi samymi wartościami kolumny?

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

id_users i id_product są klucze obce z różnych tabel.

Co chcę to usunąć tylko jeden wiersz:

1  2  1 2013 

który pojawia się dwa razy, więc po prostu chcesz go usunąć.

Próbowałem tej kwerendy:

delete from orders where id_users = 1 and id_product = 2 

Ale to będzie usunąć oba (ponieważ są one powielane). Jakieś wskazówki dotyczące rozwiązania tego problemu?

Odpowiedz

167

limit Dodaj do delete zapytania

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

Usuwa tylko jeden wiersz. Jeśli byłyby 3 z tym identyfikatorem użytkownika i produktu, to 2 pozostałoby. – Rob

+8

Tak, OP mówi (s) chce usunąć 1 wiersz. Tak właśnie robi moje zapytanie. –

+2

Tak, ale myślę, że to nie jest to, czego on/ona chce. – Rob

57

Wszystkie tabele powinny mieć klucz podstawowy (składający się z jednej lub wielu kolumn), powielanie wierszy nie ma sensu w relacyjnej bazie danych. Można ograniczyć liczbę usuwanie wierszy z wykorzystaniem LIMIT choć:

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

Ale to tylko rozwiązuje aktualny problem, powinno się pracować na większej emisji poprzez definiowanie kluczy głównych.

+0

Znalazłem to, dziękuję! – Dani

+1

Dobrze jest wspomnieć, że klucz podstawowy powinien być unikalny w relacyjnej bazie danych. – Paul

+1

@Paul To jest dokładnie to, co zamierzam powiedzieć. Ale nie zapominaj, że klucz unikalny nie jest konieczny, to klucz podstawowy. –

17

Należy podać liczbę wierszy, które należy usunąć. W twoim przypadku (i zakładam, że chcesz tylko zachować jeden) można to zrobić tak:

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) 
+0

Dziękuję Rob, ale nie ... Po prostu chcę usunąć jeden wiersz, nie przechowywać tylko jednego – Dani

+0

To nie działa dla mnie w 5.5.40, powoduje błąd składni. Jak wspomniano tutaj: http://stackoverflow.com/a/578926/1076075, wydaje się, że nie możemy użyć podkwerendy do określenia wartości klauzuli LIMIT. Dla każdego, kto próbuje coś zrobić w ten sposób, sprawdź to: http://stackoverflow.com/q/578867/1076075 –

6

Najlepszy sposób zaprojektować tabelę to dodać jeden tymczasowy rząd jako auto przyrostu i zachować jako klucz podstawowy. Tak więc możemy uniknąć powyższych problemów.

+1

Albo stały wiersz. Wiem, że to stare pytanie, ale chociaż powinienem to powiedzieć. Id są używane do tego rodzaju sytuacji. Jeśli martwisz się przestrzenią: A BIGINT ma tylko 8 bajtów! –

3

Istnieją już odpowiedzi dotyczące usuwania wiersza przez LIMIT. Idealnie powinieneś mieć klucz podstawowy w swoim stole. Ale jeśli nie ma.

dam inne sposoby:

  1. Tworząc Unique index

widzę id_users i id_product powinna być unikalna w swoim przykładzie.

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

Spowoduje to usunięcie zduplikowanych wierszy z tymi samymi danymi.

Ale jeśli nadal pojawia się błąd, nawet jeśli używasz IGNORUJ klauzulę, spróbuj tego:

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. Tworząc tabelę ponownie

Jeśli istnieje to wiele wierszy, które mają zduplikowane wartości, a następnie możesz odtworzyć ponownie tabelę