views:

232

answers:

5

Among other questions, this one asked how to delete from a join.

My question: How much of this is standard SQL? On which databases would this actually work (most notably for me would be Oracle, MySQL and SQLServer)?

A: 

I used to use similar queries when I was on an MS SQL server. Not sure about the others.

Sonny Boy
+1  A: 

DELETE ... FROM .. Is not part of the ANSI standards, nor UPDATE ... FROM ... for that matter. This includes any join syntax, since the join can only be specified with a FROM.

All vendors implement this though in one form or another.

Remus Rusanu
+1  A: 

The last time I looked at the ANSI standard, the preferred method was subqueries and not JOINs. When dealing with only one implementation, where porting your code is not an issue, then you can use vendor-specific extensions freely, when they are more efficient (though UPDATE FROM, and I imagine DELETE FROM in some scenarios, has proven unpredictable: http://is.gd/4rvkA). Personally, I typically use CTEs for a lot of DELETE operations... but my development is restricted to SQL Server and I don't have to worry much about portability at all. MERGE can also be a good choice when you are performing multiple DML operations, but again this is not implemented the same (or at all) across all vendors.

In your case, I would say stay away from DELETE FROM ... JOIN because the syntax will vary slightly on the three platforms. If you use stored procedures this is less of an issue than if the SQL is embedded in your application(s), but still a hassle nonetheless.

Aaron Bertrand
+3  A: 

Not standard according to International Standard ISO/IEC 9075:1992 Section 13.6, pages 384-386. Delete with JOIN syntax won't work in Oracle.

DCookie
+1 for actually citing the (enormous) standard.
James McNellis
Hi DCookie, see my answer for a working example of DELETE with JOIN in Oracle =)
Vincent Malgrat
Nice workaround ;-)
DCookie
Actually, your example is a DELETE FROM SELECT ..
IronGoofy
+3  A: 

Hi IronGoofy,

this will actually work in Oracle. The FROM keyword is optional: DELETE (query) is the same as DELETE FROM (query).

The rules to DELETE a JOIN are the same as the rules to update a JOIN: Oracle will modify the rows from only one table and only if there is no ambiguity in identifying the rows of the base table. Look in this SO or this SO for example.

Let's build a small example:

CREATE TABLE t_parent (ID NUMBER PRIMARY KEY, NAME VARCHAR2(10));
CREATE TABLE t_child (ID NUMBER PRIMARY KEY, 
                      parent_id NUMBER REFERENCES t_parent);
INSERT INTO t_parent VALUES (1, 'a');
INSERT INTO t_child VALUES (1, 1);
INSERT INTO t_child VALUES (2, 1);

You can delete rows from the CHILD table:

SQL> DELETE FROM (SELECT t_child.*
  2                 FROM t_child
  3                 JOIN t_parent ON t_parent.id = t_child.parent_id
  4                WHERE t_parent.name = 'a');

2 rows deleted
Vincent Malgrat
+1 Great example!
IronGoofy
How much of this is standard SQL? Maybe I should ask another SO question .. DELETE FROM SELECT ..?!
IronGoofy
Does not appear to work in MySQL 5.0
DCookie