| 网站首页 | 业界新闻 | 群组 | 人才 | 下载频道 | 博客 | 代码贴 | 编程论坛
共有 682 人关注过本帖
标题:经典的删除重复记录问题总结。
只看楼主 收藏
厨师王德榜
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:63
帖 子:411
专家分:1415
注 册:2013-2-16
结帖率:100%
  问题点数:0  回复次数:10   
经典的删除重复记录问题总结。
最近有学生在问删除表中重复记录问题,本人对此问题曾做过一些研究,现在做一个总结,算是抛砖引玉吧。
另外本文只讨论用SQL语句来解决问题,至于用VFP代码来做,以前已有前辈做了完整的示例,就不重复了。
*--------------------正文--------------------*
本文总结了四种常用的部分删除重复记录(不全删除,有条件的保留)场景:
有一个表 [jlzz1] ,原始记录如下:


情况介绍完毕。下面开始出题:
1、      以学籍号为判断依据,相同学籍号的重复记录,删除其最后一条
程序代码:
DELETE FROM jlzz1 ;
      WHERE jlzz1.id IN ( ;
    SELECT m2.mid ;
      FROM ( ;
               SELECT xjh, ;
                      xm, ;
                      max(id) AS mid ;
                 FROM jlzz1 ;
                WHERE jlzz1.xjh IN ( ;
                          SELECT cChongfu.xjh ;
                            FROM ( ;
                                     SELECT jlzz1.xjh, ;
                                            jlzz1.xm, ;
                                            count( * ) AS ts ;
                                       FROM jlzz1 ;
                                      GROUP BY xjh, ;
                                               xm ;
                                     HAVING ts > 1 ;
                                 ) AS cChongfu ;
                      )  GROUP BY xjh, ;
                         xm ;
           )  AS m2 )
运行后效果:

附件: 您没有浏览附件的权限,请 登录注册
2017-12-28 11:35
厨师王德榜
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:63
帖 子:411
专家分:1415
注 册:2013-2-16
  得分:0 

2、      以学籍号为判断依据,相同学籍号的重复记录,删除首条
程序代码:
DELETE FROM jlzz1 ;
      WHERE jlzz1.id IN ( ;
    SELECT m2.mid ;
      FROM ( ;
               SELECT xjh, ;
                      xm, ;
                      min(id) AS mid ;
                 FROM jlzz1 ;
                WHERE jlzz1.xjh IN ( ;
                          SELECT cChongfu.xjh ;
                            FROM ( ;
                                     SELECT jlzz1.xjh, ;
                                            jlzz1.xm, ;
                                            count( * ) AS ts ;
                                       FROM jlzz1 ;
                                      GROUP BY xjh, ;
                                               xm ;
                                     HAVING ts > 1 ;
                                 ) AS cChongfu ;
                      )  GROUP BY xjh, ;
                         xm ;
           )  AS m2 )
运行后效果:

附件: 您没有浏览附件的权限,请 登录注册
2017-12-28 11:38
厨师王德榜
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:63
帖 子:411
专家分:1415
注 册:2013-2-16
  得分:0 
3、      以学籍号为判断依据,相同学籍号的重复记录,只保留最后一条
程序代码:
DELETE FROM jlzz1 ;
      WHERE jlzz1.id NOT IN ( ;
    SELECT m2.mid   FROM ( ;
               SELECT xjh,xm,max(id) AS mid ;
                 FROM jlzz1 ;
                GROUP BY xjh, xm ) AS m2)
运行后效果:

附件: 您没有浏览附件的权限,请 登录注册
2017-12-28 11:40
厨师王德榜
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:63
帖 子:411
专家分:1415
注 册:2013-2-16
  得分:0 
4、      以学籍号为判断依据,相同学籍号的重复记录,只保留首条
程序代码:
DELETE FROM jlzz1 ;
      WHERE jlzz1.id NOT IN ( ;
    SELECT m2.mid   FROM ( ;
               SELECT xjh,xm,min(id) AS mid ;
                 FROM jlzz1 ;
                GROUP BY xjh, xm ) AS m2)
运行后效果:

附件: 您没有浏览附件的权限,请 登录注册
2017-12-28 11:42
厨师王德榜
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:63
帖 子:411
专家分:1415
注 册:2013-2-16
  得分:0 
附:凡有重复记录的,一律删除(不保留):
程序代码:
DELETE FROM jlzz1 ;
      WHERE jlzz1.xjh  IN ( ;
    SELECT m2.xjh   FROM ( ;
               SELECT xjh,xm,count(*) AS ts ;
                 FROM jlzz1 ;
                GROUP BY xjh, xm having ts>1 ) AS m2)
运行后效果:

附件: 您没有浏览附件的权限,请 登录注册
2017-12-28 11:43
厨师王德榜
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:63
帖 子:411
专家分:1415
注 册:2013-2-16
  得分:0 
*--------------------正文结束--------------------*
欢迎提出批评和建议。
为了 练习方便,干脆把 表也传一个上来:



[此贴子已经被作者于2017-12-28 11:49编辑过]

附件: 您没有浏览附件的权限,请 登录注册
2017-12-28 11:46
schtg
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:11
帖 子:375
专家分:510
注 册:2012-2-29
  得分:0 
@厨师王德榜,学习啦,谢谢!
2017-12-28 12:54
isealer
Rank: 2
等 级:论坛游民
帖 子:18
专家分:24
注 册:2017-8-25
  得分:0 
学习思路,多谢分享!
2017-12-28 14:27
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:版主
威 望:333
帖 子:11176
专家分:42137
注 册:2006-5-13
  得分:0 
不错的示例,有益的总结。

活到老,学到老! http://www.qs98.com E-mail:hu-jj@21cn.com
2017-12-28 19:16
我是11
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2018-1-1
  得分:0 
SELECT xjh,xm,MAX(id) as mid FROM jlzz1 WHERE jlzz1.xjh in (SELECT a.xjh from( SELECT jlzz1.xjh,jlzz1.xm,COUNT(*) as ts FROM jlzz1 GROUP BY xjh,xm  HAVING ts>1) as a) GROUP BY xjh,xm
在尝试做第一种写法的时候,我曾漏掉后面的group by 字句,软件提示group by 字句缺少或无效。为什么一定要进行分组排列呢?是因为有MAX()函数?
此外,在jlzz1.xjh、jlzz1.xm 这两个字段名,我漏写jlzz1好像也可以达到效果?是不是有什么别的用途?
新手提问,大神们别见怪……
2018-01-02 21:58







关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.087537 second(s), 8 queries.
Copyright©2004-2018, BCCN.NET, All Rights Reserved