【问题标题】:How to delete in MS Access when using JOIN's?使用 JOIN 时如何在 MS Access 中删除?
【发布时间】:2011-07-31 22:34:01
【问题描述】:

我正在尝试在 MS Access 中使用 DELETE 子句,但在使用 JOIN 子句时也遇到了问题。我注意到这可以通过使用DISTINCTROW 关键字来完成。

例如,以下 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 引擎中发生了什么需要这样做?

【问题讨论】:

  • 考虑到DELETE 作用于整行而不是列,在DELETEFROM 关键字之间指定anything 没有任何意义。

标签: sql ms-access delete-row sql-delete


【解决方案1】:
Delete Table1.*
From Table1
Where Exists( Select 1 From Table2 Where Table2.Name = Table1.Name ) = True

为了扩展我的答案,官方 SQL 规范没有特别规定在操作查询中使用联接,因为它会产生模棱两可的结果。因此,如果您可以避免在操作查询中使用 Joins,就像我在这里一样,它会更好(并且 Access 会更快乐)。 Access 需要 DISTINCTROW 的原因是,两个表之间的 Join 很可能会创建 Table1 行的重复项(即 Table2 中有多个相关行),因此 Access 会感到困惑。我还发现,如果您尝试使用 Join 并且主键不存在,Access 将会停止。一般来说,如果可以的话,最好避免在操作查询中加入。

【讨论】:

  • 你的答案是完全正确的——DISTINCTROW 的全部目的是以一种可编辑的方式将多表解析为唯一的行。
  • 我想补充一点,当使用 DISTINCTROW 不会发生的跨数据库(或访问其他数据库)连接时,上面提供的查询可能性能极差。 (在一种情况下是 20 秒而不是 1 小时后未完成)
  • @Stefan - 同一查询的另一个版本是Where PKCol In(...) = True,它消除了相关性,即使在跨数据库场景中也应该表现良好。因为在 Access 中没有分析执行计划的能力,所以在使用 Exists 函数时,无法轻松确定 DISTINCTROW 真正在做什么以及它在哪些方面做得不好。我们只能反复试验。
  • 这个查询可以通过删除'= True'冗余比较来简化。
  • 理论上...是的。但是,我似乎记得旧版本的 Access 实际上需要与布尔常量进行显式比较。
【解决方案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 也会发生(我经常在删除之前使用它)...

【讨论】:

    【解决方案3】:
    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)
    

    【讨论】:

    • 从 tblA 中删除 id in (Select id from tblB)
    • 用于连接表:
    • DELETE * FROM ttrans WHERE exists (select a.* from ttrans a,temp_tmbtrans b where ttrans.ref_code = b.ref_code and ttrans.fund_account = b.fund_account and ttrans.tr_date = b.tr_date and ttrans.tr_code = b.tr_code 和 ttrans.sharecode = b.sharecode 和 ttrans.unit = b.unit 和 ttrans.amt = b.amt 和 ttrans.price = b.price 和 ttrans.account = b.account);
    • 针对上述评论,请注意 MS Access 不支持临时表。
    猜你喜欢
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多