如何删除不在2个表的连接中的东西?

时间:2011-06-24 09:22:23

标签: sql tsql

我有一个问题,我想删除孤立的记录。我想知道删除不在连接中的记录的语法是什么。

所以,如果我的查询得到的东西(我不想删除):

select * from tbl_user tu
inner join tbl_user_group_xref tugx on tu.userid=tugx.userid

然后我该怎么做 1)获取条款中不存在的东西,2)删除它?

喜欢不使用数组,但数组解决方案仍然可用于学习目的。

5 个答案:

答案 0 :(得分:7)

尝试

delete tbl_user 
  from tbl_user tu 
  left join tbl_user_group_xref tugx on tu.userid=tugx.userid 
where tugx.userid is null

答案 1 :(得分:6)

e.g:

delete from tbl_user tu
where 
  user_id not in (
    select 
      user_id 
    from 
      tbl_user tu
    inner join 
      tbl_user_group_xref tugx on tu.userid=tugx.userid
) 

答案 2 :(得分:3)

对Duncan Howe的答案有一个优化,我知道它可以在MySQL中运行,并且可以与其他服务器一起使用。它可能也适用于t-clausen.dk在MySQL中的答案。

如果要从表t1中删除t2中没有相应行的行,并且两个表都非常大,那么服务器最终可能会被磁盘搜索所淹没。我发现如果你可以强制服务器在运行查询之前将t2的索引加载到内存中,然后在查询中强制服务器忽略t1的索引,那么性能可以大大提高。这使得服务器对t1进行顺序扫描,这将有效地利用磁盘。服务器逐步查找t1的每一行,查找内存中的t2索引,以确定是否应该删除该行。因此消除了磁盘搜索并且磁盘IO速率非常高,这使CPU保持忙碌。

例如:

delete tbl_user 
  from tbl_user tu ignore key (primary)
  left join tbl_user_group_xref tugx 
    use key (userid) on tu.userid=tugx.userid
where tugx.userid is null

(我假设tbl_user.userid是其表的PK而tbl_user_group_xref.userid上的索引名为userid。如果不是,请更改相应的键名。)

强制服务器将索引加载到内存中是特定于技术的。在MySQL for MyISAM表中,您可以使用load index into cache。从头开始重新创建索引(在MySQL中非常快)可能会将其保留在缓存中(并且具有平衡B树的良好副作用)。

我已经看到使用此优化提高了100倍的示例。只要你可以缓存t2的索引,你就可以有效地处理非常大的表。

答案 3 :(得分:1)

您可以使用此处所述的NOT IN语句http://www.techonthenet.com/sql/in.php

基本上,您可以从要从中删除记录的表中编写一个select查询,然后在连接这两个表的子查询上执行NOT IN。

我不知道这是否表现得非常好。

编辑:基本上正是Heximal所说的。

答案 4 :(得分:1)

此删除语句以及Duncan Howe的脚本执行最佳。我给了Duncan Howe一个加号,因为它是正确的,我不知道那种语法。

delete tu
from tbl_user tu 
where not exists (select 1 from tbl_user_group_xref where userid = tu.userid)