我有一个表格,用于保存所有已发生的行更改。问题是,在应用程序的开头,有一个错误,每行都有一堆副本。
表格如下所示:
copies
|ID |CID |DATA
| 1 | 1 | DA
| 2 | 2 | DO
| 2 | 3 | DO (copy of CID 2)
| 1 | 4 | DA (copy of CID 1)
| 2 | 5 | DA
| 1 | 6 | DA (copy of CID 1)
| 2 | 7 | DO
表格副本中的CID是唯一的。
我想要的是删除按CID排序的所有DATA GROUP BY ID重复项。
正如您在表中看到的那样,CID 2和3是相同的,它们是相继的。我想删除CID 3.与CID 4和CID 6相同;他们之间没有ID 1,是CID 1的副本。
删除重复项后,我希望该表看起来像这样:
copies
|ID |CID |DATA
| 1 | 1 | DA
| 2 | 2 | DO
| 2 | 5 | DA
| 2 | 7 | DO
有什么建议吗? :)
我认为我的问题很严重,因为每个人似乎认为最好的答案会给出这个结果:
ID | DATA | DATA | DATA | DATA | DATA | DATA | CID |
|Expected | Quassnoi |
1809 | 1 | 0 | 1 | 0 | 0 | NULL | 252227 | 252227 |
1809 | 1 | 0 | 1 | 1 | 0 | NULL | 381530 | 381530 |
1809 | 1 | 0 | 1 | 0 | 0 | NULL | 438158 | (missing) |
1809 | 1 | 0 | 1 | 0 | 1535 | 20090113 | 581418 | 581418 |
1809 | 1 | 1 | 1 | 0 | 1535 | 20090113 | 581421 | 581421 |
CID 252227和CID 438158是重复的,但因为CID 381530介于它们之间;我想保留这个。当按CID和ID排序时,它只是一个接一个地重复的副本。
答案 0 :(得分:5)
DELETE c.*
FROM copies c
JOIN (
SELECT id, data, MIN(copies) AS minc
FROM copies
GROUP BY
id, data
) q
ON c.id = q.id
AND c.data = q.data
AND c.cid <> q.minc
<强>更新强>
DELETE c.*
FROM (
SELECT cid
FROM (
SELECT cid,
COALESCE(data1 = @data1 AND data2 = @data2, FALSE) AS dup,
@data1 := data1,
@data2 := data2
FROM (
SELECT @data1 := NULL,
@data2 := NULL
) vars, copies ci
ORDER BY
id, cid
) qi
WHERE dup
) q
JOIN copies c
ON c.cid = q.cid
此解决方案会使MySQL
会话变量失效。
有一个纯ANSI
解决方案会使用NOT EXISTS
,但是,由于MySQL
优化器的工作方式(它不会使用range
),它会很慢相关子查询中的访问方法)。
请参阅我的博客中的这篇文章,了解相关任务的性能详情:
答案 1 :(得分:1)
您可以在子查询中使用count
:
delete from copies
where
(select count(*) from copies s where s.id = copies.id
and s.data = copies.data
and s.cid > copies.cid) > 0
答案 2 :(得分:1)
// EDITED for @Jonathan Leffler comment
//$sql = "SELECT ID,CID,DATA FROM copies ORDER BY CID, ID";
$sql = "SELECT ID,CID,DATA FROM copies ORDER BY ID, CID";
$result = mysql_query($sql, $link);
$data = "";
$id = "";
while ($row = mysql_fetch_row($result)){
if (($row[0]!=$id) && ($row[2]!=$data) && ($id!="")){
$sql2 = "DELETE FROM copies WHERE CID=".$row[1];
$res = mysql_query($sql2, $link);
}
$id=$row[0];
$data=$row[2];
}
答案 3 :(得分:0)
从副本c中删除c.cid in(选择max(cid)为max_cid,count(*)为num,其中num> 1,group by id,data)