`
zc9861692
  • 浏览: 5994 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

取出数据库中重复的记录

阅读更多

,一道笔试题,就是查询出数据表中重复的记录,应该来说用过分组查寻的,这道题并不在话下,我们先来看看这张表

上图高亮部分的是重复的数据行,那么如何取出其中高亮的部分,
聚合函数
在解决这个问题前,我们必需先讲讲sql语言中一种特殊的函数:聚合函数,例如SUM , COUNT , MAX , AVG 等。这些函数和其它函数的根本区别就是它们一般作用在多条记录上 。例如上函数从左至右依次为 求总和,记录数,最大值,平均值!关于它们的作用相信很多朋友也知道!但也有可能在自己知道的情况下,并不了解它们的学名,聚合函数 。这也是我开篇写这个的目的!
另外就是group by,分组查寻。看下面结果

通过使用GROUP BY 子句,可以让SUM 这样聚合函数对属于一组的数据起作用。当我们上面指定 GROUP BY userName时,属于同一个userName(用户)的一组数据将只能返回一行值,也就是说,表中所有除userName(用户)外的字段,只能通过 SUM, COUNT等聚合函数运算后返回一个值 。假使我们在第二句SQL语句中添加一列,userPassword时,就会报如下错误

这应该是初学者经常遇见的错误,据上已经分析过,出现此种错误是必然,因为,我们的结果是已经分组过的,所以结果会按姓名分组,相同的姓名只返回一行结 果,但并没有指定也按密码分,所以当返回姓名重复记录的时候,并不知道返回的这一行密码取哪个?因为我们没有对密码聚合,或分组,所以报错是因为密码按此 逻辑,无法取到!
那么有朋友可以会想到那么group by 后面再加上密码会怎样,可以试试。学计算机,有了想法就应该去尝试,大胆尝试。电脑也试不坏!怕什么

此时程序有了结果。对比之前的图,我们可以发现结果集不一样了,多了一行
 a   15
变成了
a     a    10
a     b      5

想想原因,因为我们现在 分组多加了密码,所以也会按姓名和密码都相同 的分!因为姓名都为a的用户有二个密码为a一个密码为b ,所以在按密码分时,会继续拆分!也就出现如上结果!

Having

那么Having又是有什么作用的?
 HAVING子句主要就是在聚合后对组记录进行筛选 。类似where,但其与where又是不同的!
让我们还是通过具体的实例来理解GROUP BY 和 HAVING 子句
第二句,也即将登录总次数大于5的记录查出!注意在这里,我们不能使用where,因为用where来限定条件,需要符合条件的列必须在表中存在!而这里的取出总登录次数大于5,表中本没有这样一列,所以无法使用where来查询,而必须使用having, 了解这个,我们就应该知道where与having的差别了!
HAVING是对由sum或其它聚合函数运算结果的输出进行限制
那么在了解了上面的知识后,我们如何再来解决开篇提到的问题,也即如何取出表中重复的记录?
我们要查出重复的记录,那么必然要用到分组查询,group by。分组的依据为表中各列。这样它会将各列都相同的分为一组,但同时我们要查询出重复的记录,因此必然需要相同的记录至少应该是2条以上。由此可知。我 们需要对group by 的结果进行限定,条件是记录数大于1的,因此 我们联想到having。因此有了如下解决方案:


那么如果同时存在where及having是什么样的呢?看下图:



还有另外一个相似的问题就是如何删除数据库中重复的记录
这个问题应该有几种解决方案,比较常用的是使用临时表,如下:

-- 使用distinct关键字查出去重后的记录,并将结果存储在临时表中
select   distinct   *   into  # temp   from  repeat   
-- 删除 repeat 表
delete  repeat   
-- 再从临时表中取出所有结果放回repeat表中
insert  repeat  select   *   from  # temp    
-- 删除临时表
drop   table  # temp


操作之后的结果与上,去掉了重复的行我用高亮做了标记。也即使用distinct关键字去重,是去掉所有列都相同的,而对于userName及userPassword相同的,它没有处理出来,现在假设要将姓名与密码都相同的也去掉,如何处理。看下面:


select   *    from  repeat a
where  
(a.userName ) 
in  ( select  userName  from  repeat  group   by  userName,userPassword  having   count ( * >   1
and  
(a.userPassword ) 
in  ( select  userPassword  from  repeat  group   by  userName,userPassword  having   count ( * >   1 )


这样取出的是用户名与密码相同的记录!将select改为delete即可删除,当然,这样删除就全部删除了,如果想要留一条,还可在后面加限定条件,来决定留下哪一条!

 

更正:经 gatusso52#163.com 网 友指出。上面这条SQL语句存在逻辑性错误,即当表中存在userName=a,userPassword=fengyan时,按上述语句查寻重复会将这 条记录查出。where userName in ……and userPassword in ……刚好也适用于 用户名为A密码为fengyan的记录!查询重复可以使用如下语句:

 

create   table  # user
(
  UserName 
varchar ( 50 ),
  UserPassword 
varchar ( 50 )
)

insert   into  # user   values ( ' fengyan ' , ' fengyan ' )

insert   into  # user   values ( ' fengyan ' , ' fengyan ' )

insert   into  # user   values ( ' fengyan ' , ' fengyan ' )

insert   into  # user   values ( ' a ' , ' a ' )

insert   into  # user   values ( ' a ' , ' a ' )

insert   into  # user   values ( ' a ' , ' fengyan ' )

-- 存在逻辑性错误的SQL语句
select   *   from  # user  a
where  
(a.userName ) 
in  ( select  userName  from  # user   group   by  userName,userPassword  having   count ( * >   1
and  
(a.userPassword ) 
in  ( select  userPassword  from  # user   group   by  userName,userPassword  having   count ( * >   1



-- 更正为
create   table  #tempuser
(
  UserName 
varchar ( 50 ),
  UserPassword 
varchar ( 50 )
)

 
DECLARE  MyCURSOR  CURSOR   
FOR
select   *   from  # user  a  group   by  userName,userPassword 
having    count ( * ) > 1

DECLARE   @userName   varchar ( 50 ), @userPassword   varchar ( 50 )
OPEN  MyCURSOR
FETCH  MyCURSOR  INTO   @userName , @userPassword
WHILE   @@FETCH_STATUS = 0  
begin
    
insert   into  #tempuser  select   *   from  # user   where  userName = @userName   and  userPassword = @userPassword
    
    
FETCH  MyCURSOR  INTO   @userName , @userPassword
end
CLOSE  MyCURSOR
DEALLOCATE  MyCURSOR
select   *   from  #tempuser


-- 有点麻烦,像是为了解决这个问题而写,没想出简单的好办法
drop   table  #tempuser

drop   table  # user

结果:

 

上面黄色标记的为开始逻辑错误的SQL语句查询。下面的记录是正确的!

分享到:
评论

相关推荐

    PHP实现在数据库百万条数据中随机获取20条记录的方法

    本文实例讲述了PHP实现在数据库百万条数据中随机获取20条记录的方法。分享给大家供大家参考,具体如下: 额,为什么要写这个? 在去某个公司面试时,让写个算法出来,当时就蒙了,我开发过程中用到算法的吗?又不是...

    删除数据库表中的父节点以及其子节点

    在数据库管理中,删除具有层级关系的数据记录是一项常见的操作,特别是在树形结构或者有父子关系的数据表中。本文将深入探讨如何使用存储过程来实现这一功能,特别关注如何删除父节点及其所有子节点。首先,我们需要...

    对象保存进MySQL数据库,从MySQL中读取出对象信息(源码)

    在IT行业中,数据库是存储和管理数据的核心...以上就是关于“对象保存进MySQL数据库,从MySQL中读取出对象信息”的相关知识点。理解并熟练掌握这些内容对于开发人员来说非常重要,能够帮助他们高效地进行数据存取操作。

    PHP查询数据库中满足条件的记录条数(两种实现方法)

    在网站开发过程中,经常需要对数据库中的记录进行查询,尤其是在需要计算用户注册数或者在插入新数据前判断是否存在重复记录时,获取满足特定条件的记录条数就显得尤为重要。本文将介绍两种在PHP中查询数据库并统计...

    数据库 综合练习.doc

    - **关系运算**:包括选择、投影、连接和笛卡尔积等,其中投影运算用于取出关系中的某些列并消去重复的元组。 ### 数据库管理员(DBA)职责 - DBA负责定义概念模式、修改模式结构、编写完整性规则等,但不包括编写...

    C#语言SQL+Access+Oracle通用版数据库操作类源码

    例如,它可能有一个方法用于将对象转换为适合存储在数据库的字符串格式,或者从数据库取出的字符串还原为原始对象。 `Taobao.ini` 文件看起来是一个配置文件,通常用来存储数据库连接信息,如服务器地址、数据库名...

    福建师大数据库期末考卷

    - 从数据库中取出满足特定条件的记录是**选择**操作,即C.选择。 16. **数据独立性**: - 保证数据独立性需要修改的是模式与外模式的映射,即C.模式与外模式。 17. **关系数据库的特征**: - 重复的选项,与行...

    数据库试卷与答案.doc

    11. **关系运算**:投影运算从关系中取出某些列,并消去重复的元组。 12. **数据转移**:将满足条件的记录插入到新表中,正确的SQL语句是D,使用`SELECT INTO`从源表筛选数据并插入到目标表。 13. **系统死锁**:...

    福师19秋《数据库管理与应用》在线作业一(答案).doc

    6. **消除重复记录**:在SQL查询中,使用DISTINCT短语可以去除结果集中重复的记录。 7. **数据安全性**:这是数据库系统的重要特性,旨在防止未经授权的访问和修改,保护数据免受泄露或破坏。 8. **撤消数据库操作...

    (完整word版)第二章-关系数据库习题(word文档良心出品).doc

    关系数据库中的投影运算可以帮助用户快速地取出关系中的某些列,并消去重复元组。投影运算是关系数据库中的一个重要概念,它可以帮助用户快速地处理关系数据库中的数据。 关系数据库是建立在严格的数学理论、集合论...

    Oracle数据库中分页查询介绍

    如果使用支持存储过程的语言,可以通过存储过程返回所需行集,这样数据库内部会处理绑定变量,应用程序只需接收请求的记录: ```sql create or replace procedure search(p_min integer, p_max integer, p_rowset ...

    区域横向重复-asp

    在ASP中处理"区域横向重复"通常是为了创建表格或者网格布局,将数据库中的多条记录并列显示在同一行。 首先,我们需要理解"区域横向重复"的概念。在网页设计中,如果有一组数据需要按照横行排列,例如一个表格的列...

    数据库原理试卷.doc

    5. 取出关系中的某些列,并消去重复的元组的关系运算称为投影运算。投影是关系代数的基本运算之一,用于提取表中特定列的值。 6. SQL语言是非过程化的语言,易学习。SQL(Structured Query Language)是一种用于...

    python使用多线程查询数据库的实现示例

    - 这段代码使用了一个简单的循环来依次查询数据库中的记录,并打印出每个查询的结果以及总的执行时间。 - 由于没有使用多线程,所有的数据库查询都是顺序执行的。这意味着在等待某个查询结果的时候,其他查询无法...

    数据库应用技术:第2章 关系运算.ppt

    另外,关系中的任何两个元组都不能完全相同,这保证了数据的唯一性,避免了重复记录。关系的顺序性意味着元组之间的顺序是无关紧要的,可以自由调整。属性是没有顺序的,但为了方便处理,我们通常按照一定的习惯来...

    计算机等级考试三级数据库知识考试题.pdf

    3. **关系的特性**:在关系数据库中,表中的每一行(记录)都是唯一的,列的顺序无关紧要,但列的值不能重复(除非是标识列或允许重复的特定列)。 4. **实体间联系**:实体之间的联系是通过公共属性实现的,这些...

    数据库原理第二章练习.doc

    15. 取出关系中的某些列,并消去重复元组的关系代数运算称为投影运算,答案是B。 16. 设W=RS,且W,R,S的元组个数分别为p,m,n,三者之间的关系是p*n,因为连接运算可能会产生重复元组,所以最小值是0,最大值是m...

Global site tag (gtag.js) - Google Analytics