PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [MySQL] Datensätze löschen


MiamiNice
2011-07-05, 12:19:28
Moin,

ich steh gerade auf dem Schlauch ...

Warum funktioniert das:


SELECT * FROM products LEFT JOIN products_to_categories ON products.products_id=products_to_categories.products_id WHERE products_to_categories.categories_id IS NULL

aber das nicht:


DELETE FROM products LEFT JOIN products_to_categories ON products.products_id=products_to_categories.products_id WHERE products_to_categories.categories_id IS NULL

und das auch nicht:


DELETE FROM products
FROM products As A LEFT JOIN products_to_categories As B
ON A.products_id = B.products_id
WHERE B.categories_id IS NULL

MfG

Marscel
2011-07-05, 12:30:14
Welcher Fehler kommt denn?

Versuch sonst

DELETE products.* FROM products ...

MiamiNice
2011-07-05, 12:37:57
Bei


DELETE FROM products
FROM products As A LEFT JOIN products_to_categories As B
ON A.products_id = B.products_id
WHERE B.categories_id IS NULL

schmeisst er ein:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM products As A LEFT JOIN products_to_categories As B
ON A.products_id = B.' at line 2

Bei

DELETE products.* FROM products AS A LEFT JOIN products_to_categories AS B ON A.products_id = B.products_id WHERE B.categories_id IS NULL

kommt

#1109 - Unknown table 'products' in MULTI DELETE

Bei

DELETE * FROM products AS A LEFT JOIN products_to_categories AS B ON A.products_id = B.products_id WHERE B.categories_id IS NULL

kommt

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '* FROM products As A LEFT JOIN products_to_categories As B
ON A.products_id = ' at line 1

Matrix316
2011-07-05, 13:15:38
Welcher Eintrag soll denn bei einem Join gelöscht werden? Der der ersten oder der der zweiten Tabelle? Oder gar alle?

Hm, mal das probieren:
http://forums.mysql.com/read.php?6,156225,156271
delete from names, prof using names inner join prof on (id = person_id) where name = 'Kiro';

bzw.

DELETE FROM products using products_to_categories a inner join products b on a.products_id = b.products_id where b.categories_id IS NULL



oder so...

Misda
2011-07-05, 13:16:15
Hab jetzt mal nachgelesen, probier mal:

DELETE products FROM products A LEFT JOIN products_to_categories B ON A.products_id = B.products_id WHERE B.categories_id IS NULL;

-> Es darf zusätzlich nicht 2x FROM vorkommen und das AS kannst auch weglassen.


The preceding examples use INNER JOIN, but multiple-table DELETE statements can use other types of join permitted in SELECT statements, such as LEFT JOIN. For example, to delete rows that exist in t1 that have no match in t2, use a LEFT JOIN:

DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;

The syntax permits .* after each tbl_name for compatibility with Access.
aus: http://dev.mysql.com/doc/refman/5.0/en/delete.html

MiamiNice
2011-07-05, 13:37:32
Welcher Eintrag soll denn bei einem Join gelöscht werden? Der der ersten oder der der zweiten Tabelle? Oder gar alle?

Hm, mal das probieren:
http://forums.mysql.com/read.php?6,156225,156271
delete from names, prof using names inner join prof on (id = person_id) where name = 'Kiro';

bzw.

DELETE * FROM products using products_to_categories a inner join products b on a.products_id = b.products_id where b.categories_id IS NULL



oder so...

Das klappt so leider auch nicht.

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near
'using products_to_categories a inner join products b on a . products_id = b . pr' at line 1

Es geht darum alle Artikel in der Tabelle "products" zu löschen welche mit keiner Seite im Onlineshop verknüpft (products_to_categories) sind. Die Tabelle "products" hat mehrere Spalten und products_id ist der Primärschlüssel.
Die Tabelle "products_to_categories" hat 3 Spalten, Primärschlüssel ist auch die "products_id" dann kommen noch 2 Spalten die anzeigen auf welcher Katalogseite der jeweilie Artikel eingebunden ist.

Der "Trick" daran ist das Artikel die nicht mit einer Seite verknüpft sind in der "products_to_categories" Tabelle gar nicht auftauchen. Deswegen der "LEFT JOIN" da dann alle Artikel aus der "products" Tabelle eine "NULL" in die 3 Spalten der "products_to_categories" Tabelle bekommen.

Mit der "Where" selektiere ich dann genau die Artikel die ein "NULL" in der jeweilige Spalte haben also genau die die nicht verknüpft sind.


Hab jetzt mal nachgelesen, probier mal:

DELETE products FROM products A LEFT JOIN products_to_categories B ON A.products_id = B.products_id WHERE B.categories_id IS NULL;

-> http://dev.mysql.com/doc/refman/5.0/en/delete.html. Es darf zusätzlich nicht 2x FROM vorkommen und das AS kannst auch weglassen.

Geht leider auch nicht.

Misda
2011-07-05, 13:40:51
Welche Engine benutzt du denn?


If you use a multiple-table DELETE statement involving InnoDB tables for which there are foreign key constraints, the MySQL optimizer might process tables in an order that differs from that of their parent/child relationship. In this case, the statement fails and rolls back. Instead, you should delete from a single table and rely on the ON DELETE capabilities that InnoDB provides to cause the other tables to be modified accordingly.

aus: http://dev.mysql.com/doc/refman/5.0/en/delete.html

Matrix316
2011-07-05, 13:47:57
Das klappt so leider auch nicht.
[...]
Auch ohne den Stern beim Delete probiert? :redface: Kanns leider net testen, weil ich nur MSSQL Datenbanken hier habe.

MiamiNice
2011-07-05, 13:52:36
Welche Engine benutzt du denn?


aus: http://dev.mysql.com/doc/refman/5.0/en/delete.html

MySQL 5.0.32
Die Befehle schmeisse ich in den phpMyAdmin 2.9.1.1
Das ganz läuft auf einem Debian Etch Server (joar bissel älter)

Auch ohne den Stern beim Delete probiert? :redface: Kanns leider net testen, weil ich nur MSSQL Datenbanken hier habe.

Ja, habs mit Stern und ohne Stern alles schon durch. Normal müsste es klappen, ich habe echt keine Idee warum er nicht das macht was ich ihm sage :frown:

Senior Sanchez
2011-07-05, 13:58:34
MySQL 5.0.32
Die Befehle schmeisse ich in den phpMyAdmin 2.9.1.1
Das ganz läuft auf einem Debian Etch Server (joar bissel älter)

Ich glaube er meinte direkt die DB-Engine. Standard ist seit v5 glaube ich InnoDB, davor war es MyISAM.

MiamiNice
2011-07-05, 14:08:32
Ja ist eine InnoDB Engine.

The preceding examples use INNER JOIN, but multiple-table DELETE statements can use other types of join permitted in SELECT statements, such as LEFT JOIN. For example, to delete rows that exist in t1 that have no match in t2, use a LEFT JOIN:
DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;

The syntax permits .* after each tbl_name for compatibility with Access.

If you use a multiple-table DELETE statement involving InnoDB tables for which there are foreign key constraints, the MySQL optimizer might process tables in an order that differs from that of their parent/child relationship. In this case, the statement fails and rolls back. Instead, you should delete from a single table and rely on the ON DELETE capabilities that InnoDB provides to cause the other tables to be modified accordingly.

Mh...

DELETE products FROM products LEFT JOIN products_to_categories ON products.products_id=products_to_categories.products_id WHERE products_to_categories.products_id IS NULL;

Das sollte so gehen

Misda
2011-07-05, 14:15:27
Benutzt du auch Fremdschlüssel in deinem DB-Schema?

MiamiNice
2011-07-05, 14:31:30
Hah :)

DELETE products FROM products LEFT JOIN products_to_categories ON products.products_id=products_to_categories.products_id WHERE products_to_categories.products_id IS NULL;

Das hat es gebracht. Verstehe nur nicht warum gerade jetzt. Die selbe Syntax hatte ich fast als erstes probiert.

Danke euch allen.

Gast
2011-07-06, 08:26:53
Im Zweifel hättest du es vermutlich auch mit einem Sub-Select lösen können!?

xxxgamerxxx
2011-07-06, 13:10:19
Geht das auch bei MySql?:

DELETE FROM p FROM products p
LEFT JOIN products_to_categories pc ON p.products_id = pc.products_id WHERE pc.products_id IS NULL

Senior Sanchez
2011-07-06, 13:15:12
Geht das auch bei MySql?:

DELETE FROM p FROM products p
LEFT JOIN products_to_categories pc ON p.products_id = pc.products_id WHERE pc.products_id IS NULL

Also zwei Froms in einem Statement finde ich immer sehr seltsam. Geht sowas überhaupt? (ich rede jetzt nicht von irgendwelchen nested statements)

xxxgamerxxx
2011-07-06, 14:40:28
Also zwei Froms in einem Statement finde ich immer sehr seltsam. Geht sowas überhaupt? (ich rede jetzt nicht von irgendwelchen nested statements)

Ja, so mache ich das beim Sql Server (steht auch so in der MSDN). Ist irgendwie auch logisch, denn beim Update mit Join macht man es ja auch so (also den Bezug auf Tabelle/Alias).

Senior Sanchez
2011-07-06, 21:35:48
Also ich habe mal versucht, etwas näheres rauszubekommen, aber es scheint, dass dieses delete from ... from ... nicht Bestandteil des SQL-92 Standards ist. Insofern ist so etwas schon kritisch zu verwenden.

Ich selber nutze auf Arbeit momentan MySQL, aber ich habe da auch noch kein delete from from benutzt, weil ich es nicht brauche. Viel praktischer fänd ich da übrigens, wenn MyISAM Fremdschlüssel beherrschen würde.

Tiamat
2011-07-06, 22:24:31
@TS: Klar so muss das gehen.
Ich hätte gleich mal das ausprobiert, was ich immer als fallback mache, wenn ich irgendwo n Wurm bei komplexen Joins drinhabe:

delete from products where products.p_id = products_to_cat.p_id AND
products_to_cat.cat_id is NULL

Gruß
Tiamat

Gast
2011-07-06, 22:40:04
nicht Bestandteil des SQL-92 Standards ist.

Kann schon sein, dass das eine T-SQL spezifische Sache ist. In dem Fall geht es dann wahrscheinlich nicht für MySql.

Ich persönlich halte mich hier aber lieber an die Dokumentation, da für mich Kompatibilität zu T-SQL wichtiger ist. Meine Statements verwenden sowieso zum Großteil T-SQL spezifische Dinge.

Berni
2011-07-09, 00:30:44
Im Zweifel hättest du es vermutlich auch mit einem Sub-Select lösen können!?
Das würde ich auch empfehlen oder genauer gesagt sowas:
DELETE FROM products a where not exists(Select 1 FROM products_to_categories b WHERE a.products_id=b.products_id)

Matrix316
2011-07-09, 10:33:40
Geht Delete mit Alias?

Berni
2011-07-09, 17:02:05
Du hast recht, geht bei MySQL nicht per Alias. Da muss man es so machen:
DELETE FROM products where not exists(Select 1 FROM products_to_categories WHERE products_id=products.products_id)