Access 查询同一张表中某个字段含有重复项的记录

时间:2022-02-28 13:27:36

 标题起得有点长,不过我要把文章主题表达的精确点。我的测试环境是Access 2003,操作对象是单一的表,目标是要把某个字段含有重复项的记录找出来。围绕这个目标再展开谈点相关的SQL语句。在两张表里查找匹配记录的方法我在另一篇日志记载过

我工作中维护的表,虽然都有主键,但是很多主键是自动生成的,并不能保证实际意义上的数据没有重复值。举例说,有张“Student”表,主键类型是“AutoNumber”。不用名字作主键,是因为中国人重名的很多。但是不时的,我需要看看有哪些名字重复出现,判断一下到底是真的两个人呢还是不留神把同一个人输了两遍。

先看一下数据样本:表名 Student

ID  Name City  Address
1 包彦钦  北京  北京市东四北大街520号
2 王洪涛  北京   北京市西单北大街151号
3 张立涛   大连   大连市西岗区新开路69号
4 佘高峰  济南  山东省济南市泺文路50号
5  徐俊  上海  上海市静安区南阳路46号
6  张忠飞  上海   上海市肇嘉浜路414号
7  徐俊   上海   上海市乳山路150号

Access 2003提供了“查找重复项查询向导”(Find Duplicates Query Wizard),可以很方便的帮你达成目标,这个向导的说明文字是这样的:This wizard creates a query that finds records with duplicate field values in a single table or query.
这个向导的使用方法网上有很多文章说过了,我就不再赘述。推荐MS官方网站的一篇:在 Access 中查找并删除重复记录。(这篇文章读起来有点拗口,可能是翻译的。)

我关心的是得出结果的SQL语句,比如要查找重复的名字,用向导生成的SQL语句是这样的:

SELECT student.Name, student.City, student.Address
FROM student
WHERE (((student.Name) In (SELECT [Name] FROM [student] As Tmp GROUP BY [Name] HAVING Count(*)>1 )))
ORDER BY student.Name;

结果是:

  Name   City   Address
 徐俊 上海 上海市乳山路150号
 徐俊 上海 上海市静安区南阳路46号

分析下这条SQL语句。这里用了子查询“select name from student group by name having count(*)>1”。这个子查询的意思是:把student表里的记录按名字组合在一起,并把组合后数量大于1的记录返回。就这个例子而言,这条子查询的返回值只有一行——“徐俊”。

接下来,我们用“徐俊”这个值替换原来的子查询,原来的SQL语句就可以简化成:
SELECT Name, City, Address FROM student
WHERE(Name  In ("徐俊")) ORDER BY Name;

Order By 的好处是在记录很多的时候,把相同的名字排在一起,便于比较其它的字段。比如比较“徐俊”的城市和地址,猜想他可能是搬家了,也可能就是两个人。

上面是讲如何把有重复值的记录列出来,如果想列出没有重复值的记录的话,在上面的基础上加个“Not”。

SELECT Name, City, Address FROM student
WHERE ( Name Not  In (SELECT [Name] FROM [student] GROUP BY [Name] HAVING Count(*)>1 ))
ORDER BY Name;

把所有记录看成全集U,重复和不重复把全集分成不相交的两部分,子查询得出有重复项的子集A,not A就是A的补集,就是不重复的那部分。

有的时候,某个字段有重复记录是正常的,比如上例中的城市,我们可以用city做准则,列出有不止一个学员的城市以及学员信息,或列出只有一个学员的城市和学员信息。

SELECT City, Name, Address FROM student
WHERE ( City In (SELECT [city] FROM [student] GROUP BY [city] HAVING Count(*)>1 ))
ORDER BY City; (列出不止一个学员的城市和学员信息)

拓展一下,列出有两个以上学员的城市和学员信息:

SELECT City, Name, Address FROM student
WHERE ( City In (SELECT [city] FROM [student] GROUP BY [city] HAVING Count(*)>2 ))
ORDER BY City;

补充:Access 查询同一张表中两个或以上字段含有重复项的记录