我有一个问题,我想删除孤立的记录。我想知道删除不在连接中的记录的语法是什么。
所以,如果我的查询得到的东西(我不想删除):
select * from tbl_user tu
inner join tbl_user_group_xref tugx on tu.userid=tugx.userid
然后我该怎么做 1)获取条款中不存在的东西,2)删除它?
喜欢不使用数组,但数组解决方案仍然可用于学习目的。
答案 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)