从表中删除重复项,其中有两个要考虑的变量

时间:2010-11-02 20:54:40

标签: php mysql database duplicates sql-delete

我们有一个使用(自动增量)ID,ClassID,StudentID设置的表。班级ID适用于学生正在上课的班级。有时我们的系统会在同一个班级中创建同一个学生的副本。我们目前正在努力解决这个问题。它可能与按下后退按钮有关。

学生经常上下一堂课,所以我们不想删除学生的副本。我们希望删除包含在同一classID中的重复学生。
例如:

ID | ClassID | StudentID
1  |   1     |     1
2  |   2     |     1
3  |   2     |     1
4  |   2     |     2
5  |   2     |     2

我想删除ID 3和5.我在互联网上搜索了这个答案,似乎无法找到它。我发现的最好的是分组但是如何对每个class id进行分组并在每个classID分组中查找重复项?

5 个答案:

答案 0 :(得分:3)

我读了一篇有关此类内容的有趣文章。众所周知,执行像这样的查询来删除重复项并不是一件好事:

SELECT ClassID, StudentID
FROM your_table
GROUP BY ClassID, StudentID;

在这种情况下,DISTINCT将是最佳解决方案。但是,有时最好从上面的错误语法开始,以便进行良好的查询。首先,让我们选择重复的对:

SELECT ClassID, StudentID
FROM your_table
GROUP BY ClassID, StudentID
HAVING COUNT(*) > 1;

您可能知道或不知道,您无法使用DELETE查询中的子查询删除行。你必须使用临时表。完成这个的完整代码就是这个:

CREATE TEMPORARY TABLE keep_lines AS 
    SELECT MAX(id) AS id_to_keep -- you can use MIN if wanted
    FROM your_table
    GROUP BY ClassID, StudentID;

DELETE FROM your_table
WHERE id NOT IN (SELECT id_to_keep
                 FROM keep_lines);

DROP TABLE keep_lines;

然后,正如许多其他人所说,为你的表添加一个UNIQUE约束!

答案 1 :(得分:2)

您不能使用同一个表格的DELETEUPDATE条记录来引用。因此,您需要创建一个临时表作为参考。或者创建一个PHP脚本,它将触发匹配ID的DELETE命令。

以下是一个示例SQL查询:

SELECT MIN(ID) AS minID, ClassID, StudentID
FROM the_table GROUP BY ClassID, StudentID HAVING COUNT(StudentID) > 1

你可以多次运行它,它会继续删除重复项。

答案 2 :(得分:0)

您可以使用以下SQL语句删除除最早的唯一行之外的所有行:

create temporary table unique_ids as
select min(id) as ID
  from some_table
 group by ClassID, StudentID;

delete some_table
  from some_table
       left join unique_ids using (id)
 where unique_ids.id is null;

如果您在大型表上运行,请考虑在创建临时表后添加索引。

答案 3 :(得分:0)

您可以找到另一个approuch here。 但是对ClassID和StudentID的唯一键约束是你明确需要做的事情。

答案 4 :(得分:0)

我强烈建议使用临时表的解决方案。简单,快速,无需复杂查询。只需创建一个类似的表(可能是type = MEMORY表示速度),然后使用简单的select distinct查询插入所有行,截断原始表并将表数据替换为临时表中的数据。

当然,这仅适用于可在生产期间停止生产的数据库。