45IT.COM- 电脑学习从此开始!
DIY硬件教程攒机经验装机配置
设计Photoshop网页设计特效
系统注册表DOS系统命令其它
存储主板显卡外设键鼠内存
维修显卡CPU内存打印机
WinXPVistaWin7unix/linux
CPU光驱电源/散热显示器其它
修技主板硬盘键鼠显示器光驱
办公ExcelWordPowerPointWPS
编程数据库CSS脚本PHP
网络局域网QQ服务器
软件网络系统图像安全
页面导航: 首页 > 设计学院 > 网络编程 > 数据库 >

怎样查询数据库中重复的数据(2)

电脑软硬件应用网 45IT.COM 时间:2012-10-17 23:19 作者:佚名

八、
相信很多人在查询数据库时都会碰到检索某表中不重复记录的时候,提到检索不重复记录,马上想到的肯定是Distinct或者Group By分组,
小弟在初次使用的时候碰到了一些麻烦,这里拿出来与大家分享,希望对更多的朋友有所帮助!

    先看看数据库表结构:
        表名: TEST 字段: Id,A,B,C,D
        其中B字段包含重复值;

Id
A B
C D
1
11 a
34 bvb
2
22 a
35 fgfg
3
33 d
ht sdf
4
44 a
345 de
5
55 c
sfsf sscv
6
66 b
rt fg
   
下面我们来看看用什么样的SQL语句检索出不含重复记录的数据:
使用Distinct关键字
    Distinct关键字主要用来在SELECT查询记录中根据某指定字段的值去除重复记录
    SELECT DISTINCT [字段名] FROM [表名] WHERE [检索条件字句]

    所以用这样一句SQL就可以去掉重复项了:
     
   SELECT DISTINCT (B) FROM TEST

    但是:

    这里有一个非常非常需要注意的地方:
    SELECT DISTINCT [字段名]后面不能再跟其他的字段,否则检索出来的记录仍然会含有重复项;
      错误写法:
            SELECT DISTINCT [字段名] ,[其他字段名] FROM [表名] WHERE [检索条件字句]
   
    实际上,我们上面SQL语句结果集里就只有B字段;(一般情况下,这种结果应该是很难满足需求的)


    如果我们的记录集里还需要有其他字段值,那怎么办呢?

实际上,我们完全可以用另一种办法来解决问题;只是需要用到子查询而已!

使用GROUP BY 分组
    有一点需要注意:
       使用带有GROUP BY字句的查询语句时,在SELECT列表指定的列要么是GROUP BY 指定的列,要么包含聚合组函数

    所以用这样一句SQL就可以去掉重复项了:
SELECT * FROM TEST WHERE id in (SELECT MIN(id) FROM TEST GROUP BY B)

    这样就得到我们想要的结果集了:
    Id
A B
C D
1
11 a
34 bvb
3
33 d
ht sdf
5
55 c
sfsf sscv
6
66 b
rt fg

      


九、mysql
----------------------------------------------------------------------

我的mysql表中的帐号是8位的随机数,我现在想查帐号有没有重复的,应该怎样操作,

----------------------------------------------------------------------

select count(*) as num,帐号 from TABLE GROUP BY 帐号
num > 1 就有重复!

十、着急的人直接看红字
在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了很久,用distinct不能解决的话,我只有用二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的。所以我花了很多时间来研究这个问题,网上也查不到解决方案,期间把容容拉来帮忙,结果是我们两人都郁闷了。。。。。。。。。

下面先来看看例子:

     table
   id    name
   1      a
   2      b
   3      c
   4      c
   5      b

库结构大概这样,这只是一个简单的例子,实际情况会复杂得多。

比如我想用一条语句查询得到name不重复的所有数据,那就必须使用distinct去掉多余的重复记录。

select distinct name from table
得到的结果是:

   name
   a
   b
   c

好像达到效果了,可是,我想要得到的是id值呢?改一下查询语句吧:

select distinct name, id from table

结果会是:

   id    name
   1      a
   2      b
   3      c
   4      c
   5      b

distinct怎么没起作用?作用是起了的,不过他同时作用了两个字段,也就是必须得id与name都相同的才会被排除。。。。。。。

我们再改改查询语句:

select id, distinct name from table

很遗憾,除了错误信息你什么也得不到,distinct必须放在开头。难到不能把distinct放到where条件里?能,照样报错。。。。。。。

很麻烦吧?确实,费尽心思都没能解决这个问题。没办法,继续找人问。

拉住公司里一JAVA程序员,他给我演示了oracle里使用distinct之后,也没找到mysql里的解决方案,最后下班之前他建议我试试group by。

试了半天,也不行,最后在mysql手册里找到一个用法,用group_concat(distinct name)配合group by name实现了我所需要的功能,兴奋,天佑我也,赶快试试。

报错。。。。。。。。。。。。郁闷。。。。。。。连mysql手册也跟我过不去,先给了我希望,然后又把我推向失望,好狠哪。。。。

再仔细一查,group_concat函数是4.1支持,晕,我4.0的。没办法,升级,升完级一试,成功。。。。。。

终于搞定了,不过这样一来,又必须要求客户也升级了。

突然灵机一闪,既然可以使用group_concat函数,那其它函数能行吗?

赶紧用count函数一试,成功,我。。。。。。。想哭啊,费了这么多工夫。。。。。。。。原来就这么简单。。。。。。

现在将完整语句放出:

select *, count(distinct name) from table group by name

结果:

   id name count(distinct name)
   1 a 1
   2 b 1
   3 c 1

最后一项是多余的,不用管就行了,目的达到。。。。。

唉,原来mysql这么笨,轻轻一下就把他骗过去了,郁闷也就我吧(对了,还有容容那家伙),现在拿出来希望大家不要被这问题折腾。

哦,对,再顺便说一句,group by 必须放在 order by 和 limit之前,不然会报错,差不多了,发给容容放网站上去,我继续忙碌。。。。。。

-----------------------------------------------------------------------------------------

更郁闷的事情发生了,在准备提交时容容发现,有更简单的解决方法。。。。。。

select id, name from table group by name
select * from table group by name

十一、查询及删除重复记录的方法
(一)
1、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断
select * from people
where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1)

2、删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowid最小的记录
delete from people
where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1)
and rowid not in (select min(rowid) from people group by peopleId having count(peopleId )>1)

3、查找表中多余的重复记录(多个字段)
select * from vitae a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)

4、删除表中多余的重复记录(多个字段),只留有rowid最小的记录
delete from vitae a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)

5、查找表中多余的重复记录(多个字段),不包含rowid最小的记录
select * from vitae a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)

(二)
比方说
在A表中存在一个字段“name”,
而且不同记录之间的“name”值有可能会相同,
现在就是需要查询出在该表中的各记录之间,“name”值存在重复的项;
Select Name,Count(*) From A Group By Name Having Count(*) > 1

如果还查性别也相同大则如下:
Select Name,sex,Count(*) From A Group By Name,sex Having Count(*) > 1

(三)
方法一

declare @max integer,@id integer
declare cur_rows cursor local for select 主字段,count(*) from 表名 group by 主字段 having count(*) >; 1
open cur_rows
fetch cur_rows into @id,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max
delete from 表名 where 主字段 = @id
fetch cur_rows into @id,@max
end
close cur_rows
set rowcount 0

  方法二

  有两个意义上的重复记录,一是完全重复的记录,也即所有字段均重复的记录,二是部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略。

  1、对于第一种重复,比较容易解决,使用

select distinct * from tableName

  就可以得到无重复记录的结果集。

  如果该表需要删除重复的记录(重复记录保留1条),可以按以下方法删除

select distinct * into #Tmp from tableName
drop table tableName
select * into tableName from #Tmp
drop table #Tmp

  发生这种重复的原因是表设计不周产生的,增加唯一索引列即可解决。

  2、这类重复问题通常要求保留重复记录中的第一条记录,操作方法如下

  假设有重复的字段为Name,Address,要求得到这两个字段唯一的结果集

select identity(int,1,1) as autoID, * into #Tmp from tableName

select min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoID

select * from #Tmp where autoID in(select autoID from #tmp2)

  最后一个select即得到了Name,Address不重复的结果集(但多了一个autoID字段,实际写时可以写在select子句中省去此列)

(四)
查询重复
select * from tablename where id in (
select id from tablename
group by id
having count(id) > 1
)

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
无法在这个位置找到: baidushare.htm
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
验证码:点击我更换图片
推荐知识