SQL Verwaiste Einträge löschen

orbit

Ensign
Registriert
Dez. 2004
Beiträge
253
Hallo,

meine Datenbank hat 4 Tabellen. Ich möchte alle Daten löschen die keinen Verweis über den primary key von Tabelle1 zur Tabelle2 haben. Zusätzlich sollen auch alle anderen Verweise gelöscht werden falls in Tabelle2 kein Eintrag zu Tabelle1 gehört.

Mit diesem Befehl lasse ich mir alle anzeigen aber ich weiß nicht wie der Befehl lauten müsste um diese Einträge zu löschen.
Code:
SELECT *
FROM Tabelle1 LEFT OUTER JOIN Tabelle2
ON Tabelle1.id = Tabelle2.aid
WHERE Tabelle2.aid IS NULL

Kann mir da jemand weiterhelfen?
 
Zuletzt bearbeitet:
Code:
DELETE
FROM Tabelle1 LEFT OUTER JOIN Tabelle2
ON Tabelle1.id = Tabelle2.id
WHERE Tabelle2.id IS NULL

Würde ich spontan jetzt sagen.

mfg Jojo
 
Hallo der_noname,


Lesen
PHP:
SELECT *
FROM Tabelle1 
FULL JOIN Tabelle2
		ON Tabelle1.id = Tabelle2.id
WHERE Tabelle1.id IS NULL OR Tabelle2.id IS NULL

Löschen, geht nur je Tabelle
PHP:
DELETE FROM Tabelle1
FROM Tabelle1 
LEFT JOIN Tabelle2
	ON Tabelle1.id = Tabelle2.id
WHERE Tabelle2.id IS NULL

PHP:
DELETE FROM Tabelle2
FROM Tabelle1 
RIGHT JOIN Tabelle2
	ON Tabelle1.id = Tabelle2.id
WHERE Tabelle1.id IS NULL
Das "outer" kann übrigens immer weggelassen werden.
 
Zuletzt bearbeitet:
Jojo_44 schrieb:
Code:
DELETE
FROM Tabelle1 LEFT OUTER JOIN Tabelle2
ON Tabelle1.id = Tabelle2.id
WHERE Tabelle2.id IS NULL

Würde ich spontan jetzt sagen.

mfg Jojo

Danke, das habe ich schon probiert aber es kommt ein Fehler, denke mal durch die ganzen Verwaise auf die restlichen Tabellen.

yxcv schrieb:
Hallo der_noname,


Lesen
PHP:
SELECT *
FROM Tabelle1 
FULL JOIN Tabelle2
		ON Tabelle1.id = Tabelle2.id
WHERE Tabelle1.id IS NULL OR Tabelle1.id
Leider klappt das Lesen so nicht. Bekomme "#1054 - Unknown column 'Tabelle1.id' in 'where clause'"
 
Hab erstmal nur den select Befehl versucht.
Wenn ich ihn so ändere wird er auch ausgeführt aber liefert kein Ergebnis:
PHP:
SELECT *
FROM Tabelle1
FULL JOIN Tabelle2
ON id = Tabelle2.aid
WHERE id IS NULL OR Tabelle2.aid IS NULL
Hab vorhin vergessen zu schreiben das der Schlüssel in Tabelle2 "aid" heißt. Nur bekomme ich wie gesagt leider keine Ausgabe. Mit dem Befehl aus dem 1. Post von mir aber schon.

Mit dem Befehl fürs Lesen von yxcv bekomme ich als Fehler "#1054 - Unknown column 'Tabelle1.id' in 'where clause'".

Die Spalte "id" gibt es aber in Tablle1.
 
Bekommst du etwas, wenn du "FULL OUTER JOIN" schreibst? Der Standard ist i.d.R. INNER JOIN, den du hier nicht gebrauchen kannst.
 
Darlis schrieb:
Bekommst du etwas, wenn du "FULL OUTER JOIN" schreibst? Der Standard ist i.d.R. INNER JOIN, den du hier nicht gebrauchen kannst.

Damit bekomm ich auch wieder einen Fehler wegen Syntax Error in der Zeile wo dann "FULL OUTER JOIN Tabelle2" steht.
 
Bist du dir sicher, dass es Datensätze mit Tabelle1.id gibt die in Tabelle2.aid
(und umgekehrt) nicht vorkommt?

Der Befehlt ist so korrekt.
Um Verwechselungen zu vermeiden sollte immer "Tabelle.Spalte" in ON und WHERE geschrieben werden.

Zur Erklärung:
LEFT (OUTER) JOIN = Alle Datensätze aus der ersten Tabelle werden gezeigt
RIGHT (OUTER) JOIN= Alle Datensätze aus der zweiten Tabelle werden gezeigt
FULL (OUTER) JOIN = Alle Datensätze aus beiden Tabelle werden gezeigt, egal ob die Spalten in der "ON"-Bedingung übereinstimmt oder nicht.
 
Zuletzt bearbeitet:
Warum nicht einfach:
Code:
    SELECT *
    FROM Tabelle1 WHERE id in
 (SELECT aid FROM Tabelle2 WHERE aid IS NULL)
nur ist das genau das gleiche wie:
Code:
    SELECT *
    FROM Tabelle1 WHERE id IS NULL;
Weil Du ja Tabelle1.id = Tabelle2.aid angibst.

Du solltest Dir aber mal Gedanken über Dein Datenbank Design machen, man kann Spalten mit NOT NULL definieren und Foreign Keys verwenden, dann hat man so einen Datenmüll garnicht erst.
 
Danke erstmal an alle.

Nochmal eine kleiner Erläuterung:
Die Datenbank hat insgesamt 4 Tabellen. Tabelle1 hat den Schlüssel "id" und Tabelle2 "aid". Die restlichen Tabellen sind dann wiederum über die beiden Schlüssel verknüpft. Nun habe ich Einträge in Tabelle1 zu denen es keine passende "aid" in Tabelle2 gibt. Um auch alle anderen Verwaise mit den anderen Tabellen zu sehen habe ich den Befehl aus dem 1. Beitrag genommen.
Es soll also alles was mit der "id" aus Tabelle1 zusammenhängt gelöscht werden falls es keine "aid" in Tabelle2 zu der "id" in Tabelle1 gibt.
 
Man kan bei keinen/wenigen ein select und delete auf die gleiche tabelle machen,
daher muss man mit einer zwischen tabelle arbeiten die halt das ergebnis speichert und
dann als basis für den löschvorgang genommen wird.

Code:
create table temp_tbl AS
    SELECT Tabelle1.id, Tabelle2.aid
    FROM Tabelle1
    LEFT JOIN Tabelle2
      ON Tabelle1.id = Tabelle2.aid
    WHERE Tabelle2.aid IS NULL;

Das wäre die temp table.

Code:
Delete from tabelle1
where id in(select id from temp_tbl);

Und so wäre dann das löschen.
 
der_noname schrieb:
Danke erstmal an alle.

Nochmal eine kleiner Erläuterung:
Die Datenbank hat insgesamt 4 Tabellen. Tabelle1 hat den Schlüssel "id" und Tabelle2 "aid". Die restlichen Tabellen sind dann wiederum über die beiden Schlüssel verknüpft. Nun habe ich Einträge in Tabelle1 zu denen es keine passende "aid" in Tabelle2 gibt. Um auch alle anderen Verwaise mit den anderen Tabellen zu sehen habe ich den Befehl aus dem 1. Beitrag genommen.
Es soll also alles was mit der "id" aus Tabelle1 zusammenhängt gelöscht werden falls es keine "aid" in Tabelle2 zu der "id" in Tabelle1 gibt.

Du meinst dann wohl eher so etwas:
select * from Tabelle1 where Tabelle1.id NOT in (select Tabelle2.aid from Tabelle2)

Dies liefert dir alle Datensätze von Tabelle1 die keinen Eintrag in Tabelle2 haben.
 
das join was im eingangs gepostet hat,
ist ein NOT IN, nur ist es performanter als ein not in.

Daher ist der weg den er oben mit dem select bestreitet gut und richtig.
 
Wenn Performance wichtgi ist, ok, aber bei dem Kenntnisstand des TE würde ich es so einfach wie möglich halten. Da ist das select * from Tabelle1 where id NOT in (select aid from Tabelle2) sicherer und lässt sich dannn auch leicht in ein DELETE from Tabelle1 where id NOT in (select aid from Tabelle2) umwandeln.

UnKnOwN_86, denke auch über Dein DB Design und die Programmierung der Anweundunngen (z.B. Transaktionen verwenden) nach, damit es dort erst garnicht solche Einträge gibt.
 
UnKnOwN_86, denke auch über Dein DB Design und die Programmierung der Anweundunngen (z.B. Transaktionen verwenden) nach, damit es dort erst garnicht solche Einträge gibt.

Ich bin nicht der TE, du meintest wohl der_noname. Ich habe das Problem nicht.
 
Sorry, ja, der TE war gemeint und der sollte sich mal ernste Gedanken über sein DB Design machen und ggf. fachmännischen Rat diesbezüglich einholen.
 
Zurück
Oben