繁体   English   中英

如何删除表中具有另一个表中相应记录的所有记录

[英]How do I delete all the records in a table that have corresponding records in another table

我有两个表A和B.我想删除在以下查询中返回的表A中的所有记录:

SELECT A.*
FROM A , B
WHERE A.id = B.a_id AND
    b.date < '2008-10-10'

我努力了:

DELETE A 
WHERE id in (
    SELECT a_id 
    FROM B 
    WHERE date < '2008-10-10')

但这只有在内部选择实际返回一个值时才有效(如果结果集为空则不行)

注意:这必须适用于SQLServer和MySQL

编辑:更多信息

以上删除在SQLServer上100%有效

在MySQL上运行时,我得到一个“SQL语法错误”消息,指出SELECT的开始是问题。 如果我用(1,2)替换内部选择,那么它的工作原理。

@Kibbee你是对的,如果内部选择返回行,它实际上没有区别。

@Fred我得到一个“不唯一的table.alias:a”消息

我认为这应该有效(无论如何都适用于MySQL):

DELETE a.* FROM A a JOIN B b ON b.id = a.id WHERE b.date < '2008-10-10';

没有别名:

DELETE A.* FROM A JOIN B ON B.id = A.id WHERE B.date < '2008-10-10';

我不确定你的方法失败的原因。 如果内部查询返回空集,则第一个查询也应返回空集。 我不认为@Fred的解决方案是正确的,因为他似乎加入了错误的专栏。

或者您可以切换到具有相关子查询的存在语法...

Delete A 
From A
Where Exists 
      (Select * From B 
       Where B.Id = A.Id
         And B.date < '2008-10-10');

根据查询优化器的智能程度,(以及子查询将返回表B中的记录数),这可能会更快,因为存在不需要完全生成完整的结果集...它可以尽快停止因为它找到了一条记录......

你离答案还不远!

发布后:删除表A和B上的别名

DELETE FROM A
WHERE A.id in (
    SELECT B.a_id 
    FROM B
    WHERE B.date < '2008-10-10');

您还可以在子表中使用ON CASCADE,以便在父表中删除行时,它会自动删除子表中的子行。 这样,删除父行时无需担心引用完整性。

delete from a inner join b on a.id = b.a_id and b.date < '2008-10-10'

MYSQL和MSSQL中的另一个选项,但它的做法很好:

select b.ID
into #T
from 
    [Table b] with (nolock) 
where 
  b.date > '2008-10-10'

if exists (select * from #T with (nolock))
    delete from [Table a] where a.id in (select id from #T with (nolock))
    drop table #T

根据你对DELETE语句的描述,你想删除表A中的空orphants吗?

DELETE A.*
FROM A 
LEFT JOIN B ON A.id = B.a_id AND b.date > '2008-10-10'
WHERE b.id IS NULL

(请注意B中倒入的倒入方式)

在这种情况下应该做的伎俩。 我不确定MSSQL如何处理加入 - 删除,但我想它应该以相同的方式工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM