Wie lösche ich eine bestimmte Zeile aus der MySQL-Tabelle mit denselben Spaltenwerten?


153

Ich habe ein Problem mit meinen Abfragen in MySQL. Meine Tabelle hat 4 Spalten und sieht ungefähr so ​​aus:

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

id_usersund id_productsind Fremdschlüssel aus verschiedenen Tabellen.

Ich möchte nur eine Zeile löschen:

1     2     1    2013

Was zweimal erscheint, also möchte ich es nur löschen.

Ich habe diese Abfrage versucht:

delete from orders where id_users = 1 and id_product = 2

Beide werden jedoch gelöscht (da sie dupliziert werden). Irgendwelche Hinweise zur Lösung dieses Problems?

Antworten:


208

Fügen Sie ein limitin die Löschabfrage

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

3
Dadurch wird nur eine Zeile gelöscht. Wenn es 3 mit dieser Benutzer- und Produkt-ID gäbe, würden 2 übrig bleiben.
Rob

10
Ja, OP sagt (s), dass er 1 Zeile löschen möchte. Das macht meine Anfrage.
Jürgen d

2
Ja, aber ich denke, das ist nicht das, was er / sie will.
Rob

3
Danke Jürgen. Das ist alles was ich brauche!
Dani

3
Was OP wirklich tun muss, ist zuerst zu überprüfen, welche Zeilen dupliziert wurden, und dann die Duplikate zu löschen.
wbinky

64

Alle Tabellen sollten einen Primärschlüssel haben (bestehend aus einer oder mehreren Spalten), doppelte Zeilen sind in einer relationalen Datenbank nicht sinnvoll. Sie können die Anzahl der Löschzeilen wie folgt begrenzen LIMIT:

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

Aber das löst nur Ihr aktuelles Problem. Sie sollten auf jeden Fall an dem größeren Problem arbeiten, indem Sie Primärschlüssel definieren.


1
Dies ist gut zu erwähnen, dass der Primärschlüssel in einer relationalen Datenbank eindeutig sein sollte.
Paul

1
@ Paul Genau das möchte ich sagen. Vergessen Sie jedoch nicht, dass ein eindeutiger Schlüssel nicht unbedingt einen Primärschlüssel bedeutet.
Ryan Fung

20

Sie müssen die Anzahl der Zeilen angeben, die gelöscht werden sollen. In Ihrem Fall (und ich gehe davon aus, dass Sie nur einen behalten möchten) kann dies folgendermaßen geschehen:

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)

Danke Rob, aber nein ... Ich möchte nur eine einzelne Zeile löschen, nicht nur eine behalten
Dani

Dies funktioniert bei mir in 5.5.40 nicht, es wird ein Syntaxfehler ausgegeben. Wie hier erwähnt: stackoverflow.com/a/578926/1076075 , können wir anscheinend keine Unterabfrage verwenden, um den Wert einer LIMIT-Klausel anzugeben. Für alle, die versuchen, Dinge auf
Bharadwaj Srigiriraju

8

Der beste Weg, eine Tabelle zu entwerfen, besteht darin, eine temporäre Zeile als automatische Inkrementierung hinzuzufügen und als Primärschlüssel beizubehalten. So können wir solche oben genannten Probleme vermeiden.


1
Oder eine permanente Reihe. Ich weiß, dass dies eine alte Frage ist, aber ich denke, ich sollte es sagen. IDs werden für diese Art von Situation verwendet. Wenn Sie sich Sorgen um den Speicherplatz machen: Ein BIGINT besteht nur aus 8 Bytes!
Ismael Miguel

5

Es gibt bereits Antworten zum Löschen der Zeile durch LIMIT. Idealerweise sollten Sie einen Primärschlüssel in Ihrer Tabelle haben. Aber wenn nicht.

Ich werde andere Wege geben:

  1. Durch Erstellen eines eindeutigen Index

Ich sehe, dass id_users und id_product in Ihrem Beispiel eindeutig sein sollten.

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

Dadurch werden doppelte Zeilen mit denselben Daten gelöscht.

Wenn Sie dennoch eine Fehlermeldung erhalten, auch wenn Sie die IGNORE-Klausel verwenden, versuchen Sie Folgendes:

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. Durch erneutes Erstellen einer Tabelle

Wenn es mehrere Zeilen mit doppelten Werten gibt, können Sie auch eine Tabelle neu erstellen

RENAME TABLE `orders` TO `orders2`;

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

1

Sie müssen eine ID hinzufügen, die für jede Zeile automatisch erhöht wird. Danach können Sie die Zeile anhand ihrer ID löschen. Ihre Tabelle hat also eine eindeutige ID für jede Zeile und den id_user, id_product ecc ...

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.