我们有一个使用(自动增量)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分组中查找重复项?
答案 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)
您不能使用同一个表格的DELETE
或UPDATE
条记录来引用。因此,您需要创建一个临时表作为参考。或者创建一个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查询插入所有行,截断原始表并将表数据替换为临时表中的数据。
当然,这仅适用于可在生产期间停止生产的数据库。