问题描述:
一般数据库中表在设计时都会有主键来约束相同记录,但由于从外部数据源导入或其它原因造成一张表中大量相同记录的问题,可以通过SQL语句实现去除相同记录的操作:
状况一:表中主键是自动编号列ID,但实际数据存在大量重复,如果重复记录是有规律的可以通过ID值运算处理,但如果记录重复频率不一,并且数据量很多的情况下通过企业管理器手工删除是繁琐的,如果使用SQL命令,只需一句即可完成。
数据格式如下表所示:
ID | StuID | StuName | StuSex | StuAddress | StuMail |
1 | 1001 | 张扬 | 男 | 因果巷1号 | zy@163.com |
2 | 1001 | 张扬 | 男 | 因果巷1号 | zy@163.com |
3 | 1002 | 张律 | 男 | 虎丘路9号 | zl@eyou.com.cn |
4 | 1002 | 张律 | 男 | 虎丘路9号 | zl@eyou.com.cn |
5 | 1002 | 张律 | 男 | 虎丘路9号 | zl@eyou.com.cn |
6 | 1003 | 沈娴华 | 女 | 东环路36号 | sxh@163.com |
7 | 1003 | 沈娴华 | 女 | 东环路36号 | sxh@163.com |
8 | 1003 | 沈娴华 | 女 | 东环路36号 | sxh@163.com |
9 | 1004 | 杜岗 | 男 | 南园南路30号 | dgang@oceansoft.com |
10 | 1004 | 杜岗 | 男 | 南园南路30号 | dgang@oceansoft.com |
11 | 1005 | 许增英 | 女 | 人民路48-6号 | xzy@eyou.com |
12 | 1005 | 许增英 | 女 | 人民路48-6号 | xzy@eyou.com |
具体SQL命令语句:
DELETE FROM Student WHERE ID NOT IN (SELECT MAX(ID) FROM Student GROUP BY stuID,StuName,StuSex,StuAddress)
这样可以把每行除ID列以外所有相同的数据行中,只保留ID值最大的记录,其余全部删除
当然,也可以保留ID列最小的记录行,只需改为MIN(ID)即可 :
DELETE FROM Student WHERE ID NOT IN (SELECT MIN(ID) FROM Student GROUP BY stuID,StuName,StuSex,StuAddress)
状况二:表中未设主键,造成记录的重复(在SQL企业管理器中无法删除,只能通过查询分析器实现)
数据格式如下表所示:
StuID | StuName | StuSex | StuAddress | StuMail |
1001 | 张扬 | 男 | 因果巷1号 | zy@163.com |
1001 | 张扬 | 男 | 因果巷1号 | zy@163.com |
1002 | 张律 | 男 | 虎丘路9号 | zl@eyou.com.cn |
1002 | 张律 | 男 | 虎丘路9号 | zl@eyou.com.cn |
1002 | 张律 | 男 | 虎丘路9号 | zl@eyou.com.cn |
1003 | 沈娴华 | 女 | 东环路36号 | sxh@163.com |
1003 | 沈娴华 | 女 | 东环路36号 | sxh@163.com |
1003 | 沈娴华 | 女 | 东环路36号 | sxh@163.com |
1004 | 杜岗 | 男 | 南园南路30号 | dgang@oceansoft.com |
1004 | 杜岗 | 男 | 南园南路30号 | dgang@oceansoft.com |
1005 | 许增英 | 女 | 人民路48-6号 | xzy@eyou.com |
1005 | 许增英 | 女 | 人民路48-6号 | xzy@eyou.com |
这种情况,可以通过临时表的方式实现:
筛选出不同的记录(Distinct)插入新表(NewStudent)
SELECT DISTINCT * INTO NewStudent FROM Student
truncate table Student
insert Student select * from NewStudent
drop table NewStudent
--------------------------------------------------------------
删除重复的,只留一条:
alter table 表 add newfield int identity(1,1)
delete 表
where newfield not in ( select min(newfield) from 表 group by 除newfield外的所有字段)
alter table 表 drop column newfield