oracle 一个sql 查询2个表 字段拼接_混入了一些奇怪的东西?SQL小技巧之数据去重...

大家好,欢迎踏入野生程序猿的生存之道,我是你们的老朋友大猿猿!

今天聊聊数据库里怎样删除重复数据。

“重复”的定义

首先咱先明确一下什么叫重复数据,比如你有个表,好比说学生表吧,这个表里出现了两条一模一样的数据,姓名、性别、出生日期、学号、等等等等,全都一样,那么这两条数据就叫重复数据。当然,重复的也不一定是两条,可能一个学生出现了20条,这20条都是重复的,或者张三出现了3条,李四出现了4条等等。

d04e02ede66e1008da761c76559e9725.png

有主键

5df776528b87596bbdd9d3fc86b48b68.png

无主键

重复数据又可分为两种情况,第一种是这个表连主键都没有,所有字段全重复。第二种是这个表有主键,除了主键外的其他字段重复。

我们的目标

说到这里大家应该了解了,本文里的重复数据其实算是一种垃圾数据,它本不该出现,但由于各种原因,比如你导数据时重复操作了,比如你保存按钮没做控制而又发生了连击现象,等等等等。

那么出现了重复数据,我们期望怎么办呢?当然是把多余的删掉,只保留一条

解决办法--有主键

我们先捋捋思路,假设某个重复数据有n条,那么我们要删掉n-1条,留下1条,而留下的这个“1”,其实和其他数据没有任何区别,那么我们怎么定位出这个“1”呢?怎么让这个“1”和其他数据有所不同呢?说到这里,应该有同学想到了,主键肯定不一样!没错,我们就可以用主键区分,一不做二不休,我们就留主键最大的那个!直接上SQL:

delete from student T1 where id <> (select max(id) from student T2 where T1.name = T2.name and T1.age = T2.age and T1.gender = T2.gender and T1.national = T2.national and T1.addr = T2.addr)

为了保险起见,我们先把delete改成select *,看看要删的内容是不是和我们预想的一样:

06eec1577ece42578d2d369d6f453f85.png

可以看到,确实查出来的是重复的,且ID不是相同数据中最大的。我们执行delete,然后再看表中数据:

e09291adb79b9102b0c0a8868991aef4.png

可以看到,重复数据已经被删除了。注意,例子中,张三只有3条重复,另外一个张三只是恰好重名而已,其他信息不同。

解决办法--无主键

方案一:

对于无主键的情况思路也是完全一样,但是这里出现问题了,没有ID怎么办?大家不妨这样想,虽然两行数据一模一样,但是数据库自己却能区分出谁是谁,那么数据库中肯定还有其他标识以供区分!比如oracle,就会有个隐藏字段rowid。(如果你用的那个数据库他偏偏就是没有这么个标识,那就只能先给这个表加一列,然后给这列赋值成一个自增序列)

我们先把这个字段查出来看看它的真容:

select T.rowid,T.* from student T
923b0fe59bbf5395a4c3bd944a7d8615.png

虽然我们不知道rowid里到底存的是啥意思,但可以肯定的一点是,它不会和别的行重复,于是我们刚才的那个sql只需改成这样就行了:

delete from student T1 where rowid <> (select max(rowid) from student T2 where T1.name = T2.name and T1.age = T2.age and T1.gender = T2.gender and T1.national = T2.national and T1.addr = T2.addr)

方案二:

还有另一种方案,稍微笨一点。大家查询时去除重复都知道怎么写吧?没错:

select distinct * from student

看结果:

3cdab0cb3a91aa1665ea4091834ef98c.png

那么我们只需基于这个查询新建个表,然后再把原来的表干掉,最后再给新建的表改改名就OK啦:

create table student_temp as select distinct * from dy.student;drop table student;alter table student_temp rename to student;

为什么说这个方案稍微笨一点呢?因为你建完表后,还要注意原表有没有索引、权限、触发器等一系列相关的东西,如果有,你还得重新把这些东西建上。

好了小伙伴们,你学会了吗?点我头像能学习更多实用的开发小技巧,别忘了点关注哦~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值