833 Stimmen

MySQL-Fehler 1093 - In der FROM-Klausel kann die Zieltabelle für die Aktualisierung nicht angegeben werden

Ich habe eine Tabelle story_category in meiner Datenbank mit fehlerhaften Einträgen. Die nächste Abfrage gibt die beschädigten Einträge zurück:

SELECT * 
FROM  story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN 
       story_category ON category_id=category.id);

Ich habe versucht, sie zu löschen und auszuführen:

DELETE FROM story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category 
      INNER JOIN story_category ON category_id=category.id);

Aber ich erhalte den nächsten Fehler:

1093 - Sie können die Zieltabelle 'story_category' für die Aktualisierung in der FROM-Klausel nicht angeben

Wie kann ich dieses Problem lösen?

5 Stimmen

3 Stimmen

Es sieht so aus, als ob der Feature Request im MySQL Bug Tracker hier ist: keine Aktualisierung einer Tabelle und Auswahl aus derselben Tabelle in einer Unterabfrage möglich

1voto

GMB Punkte 194584

Soweit es Sie betrifft, möchten Sie Zeilen in story_category die es nicht gibt in category .

Hier ist Ihre ursprüngliche Abfrage, um die zu löschenden Zeilen zu identifizieren:

SELECT * 
FROM  story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN 
       story_category ON category_id=category.id
);

Kombinieren NOT IN mit einer Unterabfrage, die JOIN s erscheint die ursprüngliche Tabelle unnötig kompliziert. Dies kann einfacher ausgedrückt werden mit not exists und eine korrelierte Unterabfrage:

select sc.*
from story_category sc
where not exists (select 1 from category c where c.id = sc.category_id);

Nun ist es einfach, dies in eine delete Erklärung:

delete from story_category
where not exists (select 1 from category c where c.id = story_category.category_id);    

Diese Abfrage läuft auf jeder MySQL-Version und auch auf den meisten anderen Datenbanken, die ich kenne.

Demo auf DB Fiddle :

-- set-up
create table story_category(category_id int);
create table category (id int);
insert into story_category values (1), (2), (3), (4), (5);
insert into category values (4), (5), (6), (7);

-- your original query to identify offending rows
SELECT * 
FROM  story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN 
       story_category ON category_id=category.id);

| category\_id |
| ----------: |
|           1 |
|           2 |
|           3 |

-- a functionally-equivalent, simpler query for this
select sc.*
from story_category sc
where not exists (select 1 from category c where c.id = sc.category_id)

| category\_id |
| ----------: |
|           1 |
|           2 |
|           3 |

-- the delete query
delete from story_category
where not exists (select 1 from category c where c.id = story_category.category_id);

-- outcome
select * from story_category;

| category\_id |
| ----------: |
|           4 |
|           5 |

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X