sql查询列、字段重复值及操作

本文介绍三种SQL方法处理数据库中的重复记录,包括查找和删除重复记录,并提供了针对不同字段和需求的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

8.sql查询列,字段重复值及操作,与sql笔记中对应,找到的一篇好文章!
原文地址:http://www.cnblogs.com/lidabo/archive/2013/04/16/3024708.html
方法一:
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)

方法二:

现在假设数据库表名为student,里面有字段Sno(学号),ID(身份证),需要查找Sno字段重复的记录,ID字段是唯一的   这里提供两种查询的方法:

    1:通过学号和身份证字段来查询(数据库执行效率高,推荐)

    SELECT *
    FROM student AS A
    WHERE (Sno IN (SELECT Sno FROM 
student AS B WHERE A.ID <> B.ID))

    2:只通过学号字段来查询(数据库执行效率低,不推荐)

    SELECT *
    FROM student AS A
    WHERE (SELECT COUNT(*) FROM 
student WHERE Sno=A.Sno)>1

    从运行结果来看,1和2相同,但是执行效率完全不同,方法一执行一万多条数据只需要几秒钟即可,方法二则需要好几分钟,而且还有死机现象。

方法三:

有两个意义上的重复记录,一是完全重复的记录,也即所有字段均重复的记录,二是部分关键字段重复的记录,比如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子句中省去此列)
补充:

有两个以上的重复记录,一是完全重复的记录,也即所有字段均重复的记录,二是部分关键字段重复的记录,比如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子句中省去此列)
### 如何在 Oracle SQL查询字段的不同值 在 Oracle SQL 中,`DISTINCT` 是一种用于返回唯一记录的关键字。它可以帮助用户过滤掉重复的数据并仅保留不同的值。以下是关于 `DISTINCT` 的具体用法及其注意事项。 #### 使用 DISTINCT 查询单个字段的不同值 当需要查询某个字段的所有不同值时,可以使用如下语法: ```sql SELECT DISTINCT column_name FROM table_name; ``` 此语句会返回指定中的所有不重复的值[^2]。例如,假设有一个名为 `employees` 的表,其中有一 `department_id`,可以通过以下方式获取唯一的部门编号表: ```sql SELECT DISTINCT department_id FROM employees; ``` #### 使用 DISTINCT 查询多个字段的不同组合 如果希望基于多个字段的组合来查询其唯一值,则可以在 `SELECT DISTINCT` 后面出这些字段名。需要注意的是,只有那些被显式举出来的字段才会参与去重操作。例如,在同一个 `employees` 表中,如果有两分别是 `first_name` 和 `last_name`,则可以用下面的方式找到名字和姓氏的独特组合: ```sql SELECT DISTINCT first_name, last_name FROM employees; ``` 但是要注意,正如引用所提到的内容那样,当你尝试同时展示额外的信息(比如备注或其他描述性数据),而这些信息并未包含于 `DISTINCT` 子句之中时,这将会违反 SQL 标准,并引发错误。 #### 替代方案:GROUP BY 进行多字段组合去重 除了利用 `DISTINCT` 关键词外,还可以采用 `GROUP BY` 来达到相同的效果。这种方法特别适用于更复杂的场景下执行聚合运算的同时也需要去除冗余项的情况。基本形式如下所示: ```sql SELECT field1, field2, COUNT(*) FROM table_name GROUP BY field1, field2; ``` 这里不仅能够得到每组内的计数统计结果,同时也实现了按给定字段分组后的独特化处理过程[^1]。 #### 高级技术——窗口函数 ROW_NUMBER() 对于某些特定需求而言,可能单纯依靠 `DISTINCT` 或者简单的 `GROUP BY` 并不足以满足业务逻辑的要求。此时可考虑引入窗口函数如 `ROW_NUMBER()` 实现更加精细控制下的筛选机制。举个例子来说就是从一张订单详情表格里挑选出每个客户最早的一笔交易记录: ```sql WITH RankedOrders AS ( SELECT CustomerID, OrderDate, Amount, ROW_NUMBER() OVER(PARTITION BY CustomerID ORDER BY OrderDate ASC) as rn FROM Orders ) SELECT * FROM RankedOrders WHERE rn = 1; ``` 在这个脚本片段里面,我们先创建了一个临时视图 `RankedOrders` ,该视图包含了原始数据集加上每一行相对于同一客户的相对排名;接着再从中选取排名第一条目即代表各自顾客最早的那一次消费行为[^4]。 ### 总结 综上所述,针对简单情形可以直接运用 `DISTINCT` 完成任务;而对于稍微复杂一点的应用场合,则推荐选用 `GROUP BY` 结合必要的汇总指标一起工作;最后如果是涉及到更为高级别的定制型要求的话,不妨试试看借助强大的分析工具 —— 窗口函数吧!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值