2013-07-19 6 views
8

nicht angeben. Ich versuche, eine this Lösung auf meine Daten in der Tabelle in MySQL DB anzuwenden, die Duplikate enthält. Und ich bekomme einen solchen Fehler:Sie können die Zieltabelle 'NAME' für die Aktualisierung in der FROM-Klausel

SQL Error [1093] [HY000]: You can't specify target table 'NAME' for update in FROM clause 


DELETE NAME FROM NAME 
WHERE NAME.id NOT IN 
    (SELECT MIN(id) 
    FROM NAME GROUP BY col1, col2) 

Auch versucht, Aliasse zu vergeben - aber ohne Erfolg. Welchen Grund dieses Fehlers hier? Es weist im Allgemeinen darauf hin, dass SQL-Skript zyklischen Prozess erzeugen kann, aber hier sehe ich eigentlich keine relevanten - Es ist offensichtlich, dass zwei Auswahlen für DELETE und für SELECT gelöst ist - Motor muss einmal SELECT einmal tun und dann in WHERE Bedingungen verwenden für DELETE. Also - warum dieser Fehler passiert und wie kann ich meine Tabelle tatsächlich deduplizieren? =)

+1

Ihre Abfrage sieht nicht wie die aus der Lösung aus, die Sie anwenden möchten.Sie verwenden einen Join, während Sie 'NOT IN' verwenden. – eggyal

+0

@eggyal Mein Link zeigt auf den Kommentar, nicht auf die Antwort –

+0

Ah, fair genug; Das hatte ich nicht bemerkt. Dieser Kommentar ist SQL Server-spezifisch. Sie werden feststellen, dass der in der Antwort angegebene Join in MySQL funktioniert. – eggyal

Antwort

27

versuchen, dies kann Ihnen helfen,

DELETE FROM NAME 
WHERE NAME.id NOT IN (
        SELECT * FROM ( 
            SELECT MIN(id) FROM NAME GROUP BY col1,col2 
            ) AS p 
        ) 

Read more

+0

@GillBates Überprüfen Sie meine aktualisierte Antwort –

+0

Wow - nicht naheliegende Lösung! Es funktionierte! –

+0

Sie begrüßen :), schön, es hat für Sie gearbeitet! –

0

Wenn Sie Datensätze aus einer Tabelle Verwendung DELETE FROM tablename löschen möchten. Sie können hier keine Spalte angeben. Wenn Sie die Daten aus einer Spalte entfernen möchten, verwenden Sie die Anweisung UPDATE, um den Wert der Spalte auf leer oder NULL zu setzen.

3

From the manual:
"Derzeit können Sie nicht aus einer Tabelle löschen und aus derselben Tabelle in einer Unterabfrage auswählen."

Verwenden Sie eine geeignete Datenbank-Engine, oder führen Sie die Abfragen separat aus. (Speichern der von id programmatisch dazwischen.)

+0

Können Sie das Beispiel geben? – Tarik

+1

Von einer richtigen Datenbank? PostgreSQL. – aib

-1

die sintax der Lösch-

nicht den Namen der Spalten erfordern

weil mysql alle Daten löschen, die eine Bedingung

4

Ihre Anfrage erfüllen, ist richtig und würde auf anderen DBMS funktionieren, aber MySQL erlaubt Ihnen nicht, von einer Tabelle zu aktualisieren oder zu löschen und von der gleichen Tabelle in einer Unterabfrage auszuwählen. Es ist auf der offiziellen DELETE Dokumente dokumentiert.

Es könnte in zukünftigen Versionen behoben werden, aber derzeit wird Ihre Abfrage nicht unterstützt.

Eine einfache Lösung wäre, um Ihre Unterabfrage in einem Teilunterabfrage zu setzen, wie in echo_Me Antwort:

WHERE NAME.id NOT IN (SELECT * FROM (your subquery) s) 

dies MySQL zwingen, eine temporäre Tabelle mit den Ergebnissen Ihrer Unterabfrage zu erstellen, und da Sie tatsächlich nicht aus der gleichen Tabelle auswählen, aber aus einer temporären Tabelle wird diese Abfrage ordnungsgemäß ausgeführt. Die Leistungen könnten jedoch schlecht sein.

In der Regel werden Sie den Fehler # 1093 mithilfe von Joins beheben. Das ist Ihre Abfrage in Form kommen:

DELETE NAME 
FROM 
    NAME LEFT JOIN (
    SELECT col1, col2, MIN(id) min_id 
    FROM NAME 
    GROUP BY col1, col2) s 
    ON (NAME.col1, NAME.col2, NAME.id) = (s.col1, s.col2, s.min_id) 
WHERE 
    s.min_id IS NULL 

oder Sie können diese einfachere Version verwenden, die die schnellste sein sollte:

DELETE N1 
FROM 
    NAME N1 INNER JOIN NAME N2 
    ON 
    N1.col1=N2.COL1 
    AND N1.col2=N2.col2 
    AND N1.ID > N2.ID 

Fiddle here ist.

Verwandte Themen