5

我有 MySQL MyISAM 表:

表朋友(id,friend_id):

1、5

5, 1

2、6

6、2

3、7

如何删除反向记录?如果记录值«1, 5»存在值«5, 1»的记录,我需要删除«5, 1»。

感谢您的帮助!

4

4 回答 4

7
DELETE F1
FROM friends F1, friends F2
WHERE F1.friend_id = F2.id
  AND F2.friend_id = F1.id
  AND F1.id > F1.friend_id

编辑

更好的语法是:

DELETE F1
FROM friends F1
  JOIN friends F2 ON F1.friend_id = F2.id AND F2.friend_id = F1.id
WHERE F1.id > F1.friend_id

但是执行时间是一样的。

同样,我创建了这个小脚本来进行快速而肮脏的基准测试。

结果:

无索引:

达伦:600 => 400 行。时间:0.0274
标记:600 => 400 行。时间:0.4323
冷淡:600 => 400 行。时间:0.4081
尼克:600 => 400 行。时间:0.3201

列上的单独索引idfriend_id

达伦:600 => 400 行。时间:0.0201
标记:600 => 400 行。时间:0.0095
冷淡:600 => 400 行。时间:0.0059
尼克:600 => 400 行。时间:0.3257

上的唯一索引(id, friend_id)

达伦:600 => 400 行。时间:0.0168
标记:600 => 400 行。时间:0.0057
冷淡:600 => 400 行。时间:0.0041
尼克:600 => 400 行。时间:0.3209

结论:

  • Dalen:当列没有索引时最快
  • Frosty:列索引时最快(Mark 接近,在不考虑 tmp 表创建时间的情况下“索引情况”甚至更快。但是,当字段被索引时,创建 tmp 表所需的额外时间会增加)
于 2011-03-25T22:53:03.080 回答
3

尝试这个:

create temporary table tmp    
  select a.* from friends as a,friends as b 
  where a.id = b.friend_id 
    and a.friend_id = b.id    /* left out of original post */
    and a.id < b.id;

delete from friends using friends inner join tmp 
   on friends.id = tmp.id
  and friends.friend_id=tmp.friend_id;

如果朋友表非常大,则连接比其他方法更有效。

编辑:我修复了上面的“创建...选择”语句。测试了一下,工作正常。对于那个很抱歉!

于 2011-03-25T22:53:31.393 回答
2
DELETE FROM friends
WHERE (id,friend_id) IN
(   
   SELECT * FROM
   (
      SELECT t1.id,t1.friend_id
      FROM friends t1 JOIN friends t2
         ON t1.id=t2.friend_id AND t1.friend_id = t2.id
      WHERE t1.id > t1.friend_id
   ) t3
)
于 2011-03-25T22:43:23.817 回答
1
create table friends (
id int,
friend_id int ) engine = myisam;

insert into friends values (1,5),(5,1),(2,6),(6,2),(3,7);


delete from friends where (id,friend_id) in
(select * from (
select id,friend_id from friends
union all
select friend_id,id from friends ) as t
where id > friend_id
group by id,friend_id
having count(*) >  1)
于 2011-03-25T22:46:32.267 回答