我有以下MySQL表:
id rid
----- ------
1 2
2 1
2 3
3 2
1 3
3 1
我想改变它,因此每个关系只存在一行。
例如:
id rid
----- ------
1 2
2 3
1 3
答案 0 :(得分:3)
如果你总是有对(如你的例子):
delete from table
where id > rid;
这使记录保持在id
较小的位置。
如果可能不存在所有对,则:
delete t
from table t left outer join
(select least(id, rid) as lid, greatest(id, rid) as gid, count(*) as cnt
from table t2
group by least(id, rid), greatest(id, rid)
) t2
on least(t.id, t.rid) = t2.lid and greatest(t.id, t.rid) = gid
where id < rid or t2.cnt = 1;
编辑(解释):
第二个查询如何工作?说实话,我想写的是:
delete t from table t
where id < rid or
(id > rid and
not exists (select 1 from table t2 where t2.id = t.rid and t2.rid = t.id
);
也就是说,我希望将所有记录保存在id < rid
。但是,我还希望将所有单例记录保留在rid > id
。我不认为MySQL允许使用where
子句的语法。
相反,答案中的查询通过查看最小值和最大值来计算一对存在的次数。对于问题中的数据,子查询的结果是:
id rid cnt
1 2 2
2 3 2
1 3 2
因此,所有这些都会使用id < rid
来选择行。如果还有一行,请说4, 1
。它看起来像是:
lid gid cnt
1 2 2
2 3 2
1 3 2
1 4 1
在这种情况下,前三个将使用id < rid
的行。但是也会选择新行,因为cnt
为1。
如果表和中有重复项,那么查询中会有一些轻微的变化,可以做同样的事情。