基于另一个表删除表中的所有行

我似乎无法记住这个查询!

我想删除table1中ID与Table2相同的所有行。

所以:

DELETE table1 t1 WHERE t1.ID = t2.ID 

我知道我可以做一个WHERE ID IN(SELECT ID FROM table2),但我想要使用JOIN做这个查询,如果可能的话。

 DELETE Table1 FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID 
 DELETE t1 FROM Table1 t1 JOIN Table2 t2 ON t1.ID = t2.ID; 

我总是在删除语句中使用别名,因为它可以防止意外

 DELETE Table1 

导致无法在运行之前突出显示整个查询。

ANSI SQL中没有解决方法使用删除联合AFAIK。

 DELETE FROM Table1 WHERE Table1.id IN (SELECT Table2.id FROM Table2) 

稍后编辑

其他解决scheme(有时performance更快):

 DELETE FROM Table1 WHERE EXISTS( SELECT 1 FROM Table2 Where Table1.id = Table2.id) 

PostgreSQL的实现将是:

 DELETE FROM t1 USING t2 WHERE t1.id = t2.id; 

尝试这个:

 DELETE Table1 FROM Table1 t1, Table2 t2 WHERE t1.ID = t2.ID; 

要么

 DELETE Table1 FROM Table1 t1 INNER JOIN Table2 t2 ON t1.ID = t2.ID; 

我想如果你尝试了这个,你可能会获得更多的性能

 DELETE FROM Table1 WHERE EXISTS ( SELECT 1 FROM Table2 WHERE Table1.ID = Table2.ID ) 

find这个链接有用

从那里复制

通常情况下,人们希望根据另一个表中的条件从表中删除一些logging。 如何删除这些表中的一个而不删除两个表中的logging?

 DELETE DeletingFromTable FROM DeletingFromTable INNER JOIN CriteriaTable ON DeletingFromTable.field_id = CriteriaTable.id WHERE CriteriaTable.criteria = "value"; 

关键是你指定了从SELECT中删除的表的名字 。 所以,JOIN和WHERE做select和限制,而DELETE做删除。 不过,您不仅限于一张桌子。 如果您有多对多的关系(例如杂志和订阅者,通过订阅join),并且您要删除订阅者,则还需要从联接模型中删除任何可能的logging。

  DELETE subscribers, subscriptions FROM subscribers INNER JOIN subscriptions ON subscribers.id = subscriptions.subscriber_id INNER JOIN magazines ON subscriptions.magazine_id = magazines.id WHERE subscribers.name='Wes'; 

用连接删除logging也可以用LEFT JOIN和WHERE查看连接的表是否为NULL,这样就可以删除一个表中没有匹配的logging(就像准备添加关系一样)。 )示例文章来。

由于OP不要求特定的数据库,最好使用符合标准的声明。 只有MERGE在SQL标准中用于在目标表上join某些内容时删除(或更新)行。

 merge table1 t1 using ( select t2.ID from table2 t2 ) as d on t1.ID = d.ID when matched then delete; 

MERGE具有更严格的语义,可以防止某些可能被DELETE ... FROM忽略的错误情况。 它强制匹配的“唯一性”:如果源中的许多行(使用的内部语句)匹配目标中的同一行,则必须取消合并,并且必须由SQL引擎引发错误。

这将删除Table1中符合条件的所有行:

 DELETE Table1 FROM Table2 WHERE Table1.JoinColumn = Table2.JoinColumn And Table1.SomeStuff = 'SomeStuff' 

引用MSDN T-SQL DELETE (示例D):

 DELETE FROM Table1 FROM Tabel1 t1 INNER JOIN Table2 t2 on t1.ID = t2.ID 

基于另一个表删除表logging

  Delete From Table1 a,Table2 b where a.id=b.id Or DELETE FROM Table1 WHERE Table1.id IN (SELECT Table2.id FROM Table2) Or DELETE Table1 FROM Table1 t1 INNER JOIN Table2 t2 ON t1.ID = t2.ID; 

这是我知道的老,但只是一个指向任何人使用这个屁股的参考。 我刚刚尝试过,如果您使用的是Oracle,JOIN在DELETE语句中不起作用。 您会收到以下消息:

ORA-00933:SQL命令未正确结束。

虽然OP不想使用'in'语句,但是在回答Ankur Gupta时,这是我发现删除一个表中不存在于另一个表中的logging的最简单的方式,以一对多的关系:

 DELETE FROM Table1 as t1 WHERE ID_Number NOT IN (SELECT ID_Number FROM Table2 as t2) 

在Access 2016中工作就像一个魅力,对我来说。

我经常做下面这样的事情。 (这个例子来自在Linux上运行的Informix SE。)

这个例子的意义在于删除所有的房地产豁免/减排交易logging – 因为减排应用程序有一个基于real_estate表中信息的bug。

在这种情况下, last_update != null表示账户没有closures, res_exempt != 'p'表示账户不是个人财产(商业设备/家具)。

 delete from trans where yr = '16' and tran_date = '01/22/2016' and acct_type = 'r' and tran_type = 'a' and bill_no in (select acct_no from real_estate where last_update is not null and res_exempt != 'p'); 

我喜欢这个方法,因为过滤标准 – 至less对我来说 – 在创build查询的时候更容易阅读,并且从现在开始看了很多个月,并且想知道我在想什么。