2011-04-07 77 views
22

我正在尝试使用MS Access中的DELETE子句,并在使用JOIN子句时遇到问题。我注意到这可以通过使用关键字DISTINCTROW来完成。如何使用JOIN在MS Access中删除?

例如,下面的SQL语句不允许删除:

DELETE Table1.* 
FROM Table1 INNER JOIN Table2 ON Table1.Name=Table2.Name; 

不过,这一说法确实:

DELETE DISTINCTROW Table1.* 
FROM Table1 INNER JOIN Table2 ON Table1.Name=Table2.Name; 
  • 为什么使用DISTINCTROW关键字时DELETE工作?
  • 更具体地说,在JET引擎中发生了什么事情需要这个?
+2

考虑到'DELETE'对全行而不是列运行,指定* “DELETE”和“FROM”关键字之间的任何内容都没有意义。 – onedaywhen 2011-04-11 13:01:31

回答

22
Delete Table1.* 
From Table1 
Where Exists(Select 1 From Table2 Where Table2.Name = Table1.Name) = True 

要在我的答案扩大,官方SQL规范不提供使用联接在操作查询特别是因为它可以创造不明确的结果。因此,如果你可以避免在我的这里使用连接动作查询,那么它会更好(并且Access更加快乐)。 Access想要DISTINCTROW的原因是,两个表之间的Join可能会创建Table1行的重复项(即表2中有多个相关行),因此Access会感到困惑。我还发现,如果您尝试使用Join并且主键不存在,Access将会出现问题。通常,如果可以的话,最好避免在动作查询中加入。

+5

您的回答正确无误 - DISTINCTROW的全部目的是以一种可编辑的方式将多个行解析为独特的行。 – 2011-04-09 22:44:41

+2

我想补充一点,当使用跨数据库(或访问其他数据库)时,上面提供的查询性能可能会非常差,而在DISTINCTROW中不会出现这种联接。 (在一个例子中是20秒,而在1小时后还没有完成) – Stefan 2012-09-04 19:42:54

+0

@Stefan - 同一个查询的另一个版本是'Where PKCol In(...)= True',它消除了相关性,甚至在跨数据库情况下表现良好。因为没有能力分析Access中的执行计划,所以当使用Exists函数时,没有办法轻松确定DISTINCTROW真的在做什么以及它做得不好。我们只能使用试验和错误。 – Thomas 2012-09-04 20:12:20

2

需要注意的一个问题:这不适用于表/查询别名!

DELETE a.* 
from tblA as A 
where exists (select 1 from tblB as B where a.id=b.id) 

删除tblA中的所有记录!我尝试使用别名tblA和tblB单独 - 相同的结果(Access 2010)。

与SELECT同样会发生(我经常在删除前使用)...

0
DELETE a.* 
FROM tblA AS A 
WHERE EXISTS (SELECT 1 FROM tblB AS B WHERE a.id=b.id) 

试试这个

DELETE tblA 
FROM tblB 
WHERE EXISTS (SELECT * FROM tblA AS A,tblB AS B WHERE A.id=B.id) 
+0

从TBLA删除其中id中(从TBLB选择ID) – user7047561 2016-10-20 11:49:16

+0

用于连接表: – user7047561 2016-10-21 03:05:57

+0

DELETE * FROM T转变 WHERE存在(选择* 从一个T转变,temp_tmbtrans b 其中 ttrans.ref_code = b.ref_code 。和ttrans.fund_account = b.fund_account 和ttrans.tr_date = b.tr_date 和ttrans.tr_code = b.tr_code 和ttrans.sharecode = b.sharecode 和ttrans.unit = b.unit 和ttrans.amt = b.amt and ttrans.price = b.price and ttrans.account = b.account); – user7047561 2016-10-21 05:09:18