SQL删除重复数据
postgresql删除重复数据的几种方法小结
postgresql删除重复数据的⼏种⽅法⼩结在使⽤PG数据库的这段时间,总结了三种删除重复数据的⽅法,其中最容易想到的就是最常规的删除⽅法,但此⽅法性能较差,删数据耗时较久,虽容易实现,但性能太差,影响写数据的速率。
另外就是被使⽤的group by删除⽅法,效率较⾼。
还有⼀种是刚发现的,还没有验证,现在就总结下这三种删除⽅法,并验证各⾃的执⾏效率。
⾸先创建⼀张基础表,并插⼊⼀定量的重复数据。
test=# create table deltest(id int, name varchar(255));CREATE TABLEtest=# create table deltest_bk (like deltest);CREATE TABLEtest=# insert into deltest select generate_series(1, 10000), 'ZhangSan';INSERT 0 10000test=# insert into deltest select generate_series(1, 10000), 'ZhangSan';INSERT 0 10000test=# insert into deltest_bk select * from deltest;常规删除⽅法最容易想到的⽅法就是判断数据是否重复,对于重复的数据只保留ctid最⼩(或最⼤)的那条数据,删除其他的数据。
test=# explain analyse delete from deltest a where a.ctid <> (select min(t.ctid) from deltest t where a.id=t.id);QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Delete on deltest a (cost=0.00..195616.30 rows=1518 width=6) (actual time=67758.866..67758.866 rows=0 loops=1)-> Seq Scan on deltest a (cost=0.00..195616.30 rows=1518 width=6) (actual time=32896.517..67663.228 rows=10000 loops=1)Filter: (ctid <> (SubPlan 1))Rows Removed by Filter: 10000SubPlan 1-> Aggregate (cost=128.10..128.10 rows=1 width=6) (actual time=3.374..3.374 rows=1 loops=20000)-> Seq Scan on deltest t (cost=0.00..128.07 rows=8 width=6) (actual time=0.831..3.344 rows=2 loops=20000)Filter: (a.id = id)Rows Removed by Filter: 19998Total runtime: 67758.931 mstest=# select count(*) from deltest;count-------10000(1 ⾏记录)可以看到,id相同的数据,保留ctid最⼩的那条,其他的删除。
数据库中的数据去重与重复值处理
数据库中的数据去重与重复值处理在处理数据库中的数据时,我们经常会面对一个常见的问题,即重复数据。
重复数据不仅占用数据库存储空间,还可能导致数据不一致性和查询结果不准确等问题。
因此,对于数据库中的数据去重和处理重复值非常重要。
下面将介绍一些常见的数据去重和处理重复值的方法。
一、使用DISTINCT进行数据去重最常见的方法是使用SQL语句中的DISTINCT关键字。
可以在SELECT语句中使用DISTINCT关键字来消除重复的行。
例如,下面的SQL语句可以从名为"customers"的表中选择不重复的"customer_name"字段:SELECT DISTINCT customer_name FROM customers;二、使用GROUP BY进行数据去重另一种常见的方法是使用SQL语句中的GROUP BY子句进行数据去重。
GROUP BY子句根据指定的列对结果进行分组,使得每个组只出现一次。
例如,下面的SQL语句将从名为"orders"的表中选择每个"product_name"的唯一值:SELECT product_name FROM orders GROUP BY product_name;三、使用UNION进行数据合并和去重当涉及多个表或查询时,可以使用UNION操作符将结果进行合并和去重。
UNION操作符将两个或多个SELECT 语句的结果集合并成一个结果集,并自动去除重复的行。
例如,下面的SQL语句将从名为"customers"和"suppliers"的两个表中选择不重复的"company_name"字段:SELECT company_name FROM customersUNIONSELECT company_name FROM suppliers;四、使用临时表进行数据去重如果数据库中的数据量庞大,而且需要频繁进行去重操作,可以考虑使用临时表来处理。
sql中delete语句的用法
sql中delete语句的用法SQL中的DELETE语句用于从数据库中删除一条或多条记录。
它可以根据指定的条件删除满足条件的记录,也可以删除整个表中的所有记录。
下面是关于DELETE语句用法的详细介绍。
1. 删除整个表中的所有记录DELETE语句可以用于删除整个表中的所有记录。
语法如下:```DELETE FROM 表名;```示例:```DELETE FROM employees;```这条语句将从employees表中删除所有记录。
2. 删除满足条件的记录DELETE语句还可以根据指定的条件删除满足条件的记录。
语法如下:```DELETE FROM 表名 WHERE 条件;```示例:```DELETE FROM employees WHERE salary < 5000;```这条语句将删除employees表中工资小于5000的所有员工的记录。
3. 删除重复记录有时候数据库中可能存在重复的记录,可以使用DELETE语句删除重复记录。
例如,要删除employees表中重复的记录,可以使用以下语句:```DELETE FROM employees WHERE rowid NOT IN (SELECT MIN(rowid) FROM employees GROUP BY 唯一列);```其中,唯一列是指可以用来唯一标识一条记录的列。
4. 删除表中的前n条记录如果要删除表中的前n条记录,可以使用以下语句:```DELETE FROM 表名 WHERE rowid IN (SELECT rowid FROM 表名 LIMIT n);```示例:DELETE FROM employees WHERE rowid IN (SELECT rowid FROM employees LIMIT 10);```这条语句将删除employees表中的前10条记录。
5. 删除表中的后n条记录如果要删除表中的后n条记录,可以使用以下语句:```DELETE FROM 表名 WHERE rowid IN (SELECT rowid FROM (SELECT rowid FROM 表名 ORDER BY 排序列 DESC LIMIT n ) sub);```示例:```DELETE FROM employees WHERE rowid IN (SELECT rowid FROM (SELECT rowid FROM employees ORDER BY employee_id DESC LIMIT 10) sub```这条语句将删除employees表中的后10条记录。
SQL去重的三种方法汇总
SQL去重的三种方法汇总在SQL中,我们经常需要进行去重操作,以去除重复的数据。
下面将介绍三种常用的去重方法。
方法一:使用DISTINCT关键字在SELECT语句中,可以使用DISTINCT关键字来去除重复的记录。
它会从结果中过滤掉具有相同值的记录,只返回唯一的记录。
例如,要从表中选择唯一的城市名称,可以使用以下语句:SELECT DISTINCT city FROM table_name;该语句将返回一个包含唯一城市名称的结果集。
使用DISTINCT关键字的优点是非常简单和直观,适用于不需要对其他列进行处理的简单去重操作。
然而,它仅适用于从结果集中选择唯一值的情况,不能对数据进行聚合或其他处理。
方法二:使用GROUPBY语句GROUPBY语句是一种更灵活的去重方法,它不仅可以去除重复的记录,还可以对数据进行聚合。
在SELECT语句中,可以使用GROUPBY子句将结果按照一个或多个列进行分组。
通过对分组列的聚合操作,可以对分组后的数据进行统计和计算。
例如,要对表中的城市进行去重,并统计每个城市的记录数量,可以使用以下语句:SELECT city, COUNT(*)FROM table_nameGROUP BY city;该语句将返回一个包含城市名称和对应记录数量的结果集。
使用GROUPBY语句的优点是可以对数据进行灵活的处理和统计,不仅能够进行去重操作,还可以进行聚合计算。
然而,由于需要对数据进行分组和聚合操作,语法相对复杂,性能也可能有所降低。
方法三:使用子查询另一种常用的去重方法是使用子查询。
子查询是嵌套在主查询中的查询语句,可以将子查询的结果作为主查询的条件或数据源。
在去重操作中,可以使用子查询来筛选出不重复的记录。
通过将DISTINCT关键字应用于子查询的结果中,可以得到不重复的记录。
例如,要从表中选择所有不重复的城市记录,可以使用以下语句:SELECT*FROM table_nameWHERE city IN (SELECT DISTINCT city FROM table_name);该语句将返回一个包含所有不重复城市记录的结果集。
一个简单的去除重复字段的SQL查询语句
一个简单的去除重复字段的SQL查询语句2009-11-16 17:12一个简单的去除重复字段的SQL查询语句[2008-11-04 16:01:15 by rainoxu] | 分类:我的知识库今天公司里让.Net程序修改一个程序,需要去掉输出中的重复楼盘名称,一开始想到的是Distinct,但死路不通,只能改道,最终偶在网上找到了一个思路,修改了一下就有了。
先看所有记录(这是我在测试的数据库里做的):OK,我们这样来消除重复项:1.select * from table1 as awhere not exists(select 1 from table1 where logID=a.LogID and ID>a.ID)2.最近做一个数据库的数据导入功能,发现联合主键约束导致不能导入,原因是源表中有重复数据,但是源表中又没有主键,很是麻烦。
经过努力终于解决了,现在就来和大家分享一下,有更好的办法的可以相互交流。
有重复数据主要有一下几种情况:1.存在两条完全相同的纪录这是最简单的一种情况,用关键字distinct就可以去掉example:select distinct * from table(表名) where (条件)2.存在部分字段相同的纪录(有主键id即唯一键)如果是这种情况的话用distinct是过滤不了的,这就要用到主键id的唯一性特点及group by分组example:select * from table where id in (select max(id) from table group by [去除重复的字段名列表,....])3.没有唯一键ID这种情况我觉得最复杂,目前我只会一种方法,有那位知道其他方法的可以留言,交流一下:example:select identity(int1,1) as id,* into newtable(临时表) from table select * from newtable where id in (select max(id) from newtable group by [去除重复的字段名列表,....])drop table newtable关于一个去除重复记录的sql语句2009-8-24 16:33提问者:lichuanbao1234|悬赏分:30 |浏览次数:1075次我要查询一个表中content字段相同的记录的详细信息。
分享SQLServer删除重复行的6个方法
分享SQLServer删除重复⾏的6个⽅法1.如果有ID字段,就是具有唯⼀性的字段复制代码代码如下:delect table where id not in (select max(id) from table group by col1,col2,col3...)group by ⼦句后跟的字段就是你⽤来判断重复的条件,如只有col1,那么只要col1字段内容相同即表⽰记录相同。
2. 如果是判断所有字段也可以这样复制代码代码如下:select * into #aa from table group by id1,id2,....delete tableinsert into tableselect * from #aa3. 没有ID的情况复制代码代码如下:select identity(int,1,1) as id,* into #temp from tabeldelect # where id not in (select max(id) from # group by col1,col2,col3...)delect tableinset into table(...)select ..... from #temp4. col1+','+col2+','...col5 联合主键复制代码代码如下:select * from table where col1+','+col2+','...col5 in (select max(col1+','+col2+','...col5) from tablewhere having count(*)>1group by col1,col2,col3,col4)group by ⼦句后跟的字段就是你⽤来判断重复的条件,如只有col1,那么只要col1字段内容相同即表⽰记录相同。
SQL去重的三种方法汇总
SQL去重的三种方法汇总SQL去重是指在查询结果中去掉重复的记录。
在实际应用中,我们经常需要对数据库中的数据进行去重操作,以便得到准确且唯一的结果。
本文将介绍三种常用的SQL去重方法:使用DISTINCT关键字、使用GROUPBY子句、使用窗口函数以及使用临时表。
一、使用DISTINCT关键字DISTINCT关键字用于查询结果去除重复的行。
它可用于SELECT语句中,对特定的字段进行去重操作。
示例:SELECT DISTINCT column1, column2 FROM table_name;这条SQL语句将返回去除了重复行的column1和column2字段的结果集。
使用DISTINCT关键字的优点是简单易用,适用于简单的去重需求。
但它的缺点是性能较低,对于大数据量的查询,可能会导致查询时间过长。
二、使用GROUPBY子句GROUPBY子句用于将查询结果按照一些或多个字段进行分组,然后可以对每个分组进行聚合操作。
在使用GROUPBY子句时,需要使用聚合函数(如COUNT、SUM等),以便对每个分组进行统计。
示例:SELECT column1, column2 FROM table_name GROUP BY column1, column2;这条SQL语句将返回对column1和column2字段进行分组后的结果集,每组中只包含一个唯一的值。
使用GROUPBY子句的优点是性能较好,适用于对复杂的查询结果进行去重。
但它的缺点是需要对查询结果进行聚合操作,可能会导致查询结果的失真。
三、使用窗口函数窗口函数是一种高级的SQL技术,可以对查询结果进行排序、分组和聚合操作。
在去重操作中,我们可以使用窗口函数的ROW_NUMBER(函数来为每一行分配一个唯一的行号,然后根据行号进行筛选。
示例:SELECT column1, column2 FROMSELECT column1, column2, ROW_NUMBER( OVER(PARTITION BYcolumn1, column2 ORDER BY column1) AS rnFROM table_nameAStWHERE rn = 1;这条SQL语句将返回根据column1和column2字段去重后的结果集。
SQL去重的三种方法汇总
SQL去重的三种⽅法汇总
SQL去重的三种⽅法汇总
这⾥的去重是指:查询的时候, 不显⽰重复,并不是删除表中的重复项
1.distinct去重
注意的点:distinct
只能⼀列去重,当distinct后跟⼤于1个参数时,他们之间的关系是&&(逻辑与)关系,只有全部条件相同才会去重
弊端:当查询的字段⽐较多时,distinct会作⽤多个字段,导致去重条件增多
select distinct UserResult from Table1
2.group by去重
去重原理:将重复的⾏进⾏分组,相同的数据只显⽰第⼀⾏
弊端:使⽤group by后,所有查询字段都需要使⽤聚合函数,⽐较繁琐
select min(UserName)UserName,min(UserSex)UserSex,min(UserSubject)UserSubject,min(UserResult)UserResult from Table1 group by UserResult
3.row_number() over (parttion by 分组列 order by 排序列)
弊端:⼩孟还不知道
去重原理:现根据重复列进⾏分组,分组后再进⾏排序,不同的组序号为1,相同的组序号为2,排除为2的就达到了去重效果select *from
(
--查询出重复⾏
select *,row_number() over (partition by UserResult order by UserResult desc)num from Table1
)A
where A.num=1
这⾥安利第三个,row_number(),稳⼀些!。
sqlserver删除重复数据保留最大id的SQL语句
sqlserver删除重复数据保留最⼤id的SQL语句SqlServer 删除重复数据保留最⼤id的SQL语句多种⽅法:1--1、⽤于查询重复处理记录(如果列没有⼤⼩关系时2000⽤⽣成⾃增列和临时表处理,SQL2005⽤row_number函数处理)23--II、Name相同ID最⼤的记录,与min相反:4⽅法1:5Select*from #T a where not exists(select1from #T where Name= and ID>a.ID)67⽅法2:8select a.*from #T a join (select max(ID)ID,Name from #T group by Name) b on = and a.ID=b.ID order by ID910⽅法3:11select*from #T a where ID=(select max(ID) from #T where Name=) order by ID1213⽅法4:14select a.*from #T a join #T b on = and a.ID<=b.ID group by a.ID,,a.Memo having count(1)=11516⽅法5:17select*from #T a group by ID,Name,Memo having ID=(select max(ID)from #T where Name=)1819⽅法6:20select*from #T a where (select count(1) from #T where Name= and ID>a.ID)=02122⽅法7:23select*from #T a where ID=(select top1 ID from #T where Name= order by ID desc)2425⽅法8:26select*from #T a where ID!<all(select ID from #T where Name=)2728⽅法9(注:ID为唯⼀时可⽤):29select*from #T a where ID in(select max(ID) from #T group by Name)3031--SQL2005:3233⽅法10:34select ID,Name,Memo from (select*,max(ID)over(partition by Name) as MinID from #T a)T where ID=MinID3536⽅法11:37select ID,Name,Memo from (select*,row_number()over(partition by Name order by ID desc) as MinID from #T a)T where MinID=13839⽣成结果2:40/*41ID Name Memo42----------- ---- ----433 A A3445 B B24546(2 ⾏受影响)47*/484950--2、删除重复记录有⼤⼩关系时,保留⼤的其中⼀个记录51--II、Name相同ID保留最⼤的⼀条记录:5253⽅法1:54delete a from #T a where exists(select1from #T where Name= and ID>a.ID)5556⽅法2:57delete a from #T a left join (select max(ID)ID,Name from #T group by Name) b on = and a.ID=b.ID where b.Id is null5859⽅法3:60delete a from #T a where ID not in (select max(ID) from #T where Name=)6162⽅法4(注:ID为唯⼀时可⽤):63delete a from #T a where ID not in(select max(ID)from #T group by Name)6465⽅法5:66delete a from #T a where (select count(1) from #T where Name= and ID>a.ID)>06768⽅法6:69delete a from #T a where ID<>(select top1 ID from #T where Name= order by ID desc)71⽅法7:72delete a from #T a where ID<any(select ID from #T where Name=)737475select*from #T76/*77ID Name Memo78----------- ---- ----793 A A3805 B B28182(2 ⾏受影响)83*/--处理表重复记录(查询和删除)/******************************************************************************************************************************************************1、Num、Name相同的重复值记录,没有⼤⼩关系只保留⼀条2、Name相同,ID有⼤⼩关系时,保留⼤或⼩其中⼀个记录整理⼈:中国风(Roy)⽇期:2008.06.06******************************************************************************************************************************************************/ --1、⽤于查询重复处理记录(如果列没有⼤⼩关系时2000⽤⽣成⾃增列和临时表处理,SQL2005⽤row_number函数处理)--> --> (Roy)⽣成測試數據if not object_id('Tempdb..#T') is nulldrop table #TGoCreate table #T([ID] int,[Name] nvarchar(1),[Memo] nvarchar(2))Insert #Tselect 1,N'A',N'A1' union allselect 2,N'A',N'A2' union allselect 3,N'A',N'A3' union allselect 4,N'B',N'B1' union allselect 5,N'B',N'B2'Go--I、Name相同ID最⼩的记录(推荐⽤1,2,3),⽅法3在SQl05时,效率⾼于1、2⽅法1:Select * from #T a where not exists(select 1 from #T where Name= and ID<a.ID)⽅法2:select a.* from #T a join (select min(ID)ID,Name from #T group by Name) b on = and a.ID=b.ID⽅法3:select * from #T a where ID=(select min(ID) from #T where Name=)⽅法4:select a.* from #T a join #T b on = and a.ID>=b.ID group by a.ID,,a.Memo having count(1)=1⽅法5:select * from #T a group by ID,Name,Memo having ID=(select min(ID)from #T where Name=)⽅法6:select * from #T a where (select count(1) from #T where Name= and ID<a.ID)=0⽅法7:select * from #T a where ID=(select top 1 ID from #T where Name= order by ID)⽅法8:select * from #T a where ID!>all(select ID from #T where Name=)⽅法9(注:ID为唯⼀时可⽤):select * from #T a where ID in(select min(ID) from #T group by Name)--SQL2005:⽅法10:select ID,Name,Memo from (select *,min(ID)over(partition by Name) as MinID from #T a)T where ID=MinID⽅法11:select ID,Name,Memo from (select *,row_number()over(partition by Name order by ID) as MinID from #T a)T where MinID=1⽣成结果:ID Name Memo----------- ---- ----1 A A14 B B1(2 ⾏受影响)*/--2、删除重复记录有⼤⼩关系时,保留其中最⼩的⼀个记录--> --> (Roy)⽣成測試數據if not object_id('Tempdb..#T') is nulldrop table #TGoCreate table #T([ID] int,[Name] nvarchar(1),[Memo] nvarchar(2))Insert #Tselect 1,N'A',N'A1' union allselect 2,N'A',N'A2' union allselect 3,N'A',N'A3' union allselect 4,N'B',N'B1' union allselect 5,N'B',N'B2'Go--I、Name相同ID最⼩的记录(推荐⽤1,2,3),保留最⼩⼀条⽅法1:delete a from #T a where exists(select 1 from #T where Name= and ID<a.ID)⽅法2:delete a from #T a left join (select min(ID)ID,Name from #T group by Name) b on = and a.ID=b.ID where b.Id is null ⽅法3:delete a from #T a where ID not in (select min(ID) from #T where Name=)⽅法4(注:ID为唯⼀时可⽤):delete a from #T a where ID not in(select min(ID)from #T group by Name)⽅法5:delete a from #T a where (select count(1) from #T where Name= and ID<a.ID)>0⽅法6:delete a from #T a where ID<>(select top 1 ID from #T where Name= order by ID)⽅法7:delete a from #T a where ID>any(select ID from #T where Name=)select * from #T⽣成结果:/*ID Name Memo----------- ---- ----1 A A14 B B1(2 ⾏受影响)*/--3、删除重复记录没有⼤⼩关系时,处理重复值--> --> (Roy)⽣成測試數據if not object_id('Tempdb..#T') is nulldrop table #TGoCreate table #T([Num] int,[Name] nvarchar(1))Insert #Tselect 1,N'A' union allselect 1,N'A' union allselect 1,N'A' union allselect 2,N'B' union allselect 2,N'B'Go⽅法1:if object_id('Tempdb..#') is not nulldrop table #Select distinct * into # from #T--排除重复记录结果集⽣成临时表#truncate table #T--清空表insert #T select * from # --把临时表#插⼊到表#T中--查看结果select * from #T/*Num Name----------- ----1 A2 B(2 ⾏受影响)*/--重新执⾏测试数据后⽤⽅法2⽅法2:alter table #T add ID int identity--新增标识列godelete a from #T a where exists(select 1 from #T where Num=a.Num and Name= and ID>a.ID)--只保留⼀条记录goalter table #T drop column ID--删除标识列--查看结果select * from #T/*Num Name----------- ----1 A2 B(2 ⾏受影响)*/--重新执⾏测试数据后⽤⽅法3⽅法3:declare Roy_Cursor cursor local forselect count(1)-1,Num,Name from #T group by Num,Name having count(1)>1declare @con int,@Num int,@Name nvarchar(1)open Roy_Cursorfetch next from Roy_Cursor into @con,@Num,@Namewhile @@Fetch_status=0beginset rowcount @con;delete #T where Num=@Num and Name=@Nameset rowcount 0;fetch next from Roy_Cursor into @con,@Num,@Nameendclose Roy_Cursordeallocate Roy_Cursor--查看结果select * from #T/*Num Name----------- ----1 A2 B(2 ⾏受影响)*/---------------------完整代码(折叠)----------------------1--处理表重复记录(查询和删除)2/****************************************************************************************************************************************************** 31、Num、Name相同的重复值记录,没有⼤⼩关系只保留⼀条42、Name相同,ID有⼤⼩关系时,保留⼤或⼩其中⼀个记录5整理⼈:中国风(Roy)67⽇期:2008.06.068******************************************************************************************************************************************************/ 910--1、⽤于查询重复处理记录(如果列没有⼤⼩关系时2000⽤⽣成⾃增列和临时表处理,SQL2005⽤row_number函数处理)1112--> --> (Roy)⽣成測試數據1314if not object_id('Tempdb..#T') is null15drop table #T16Go17Create table #T([ID]int,[Name]nvarchar(1),[Memo]nvarchar(2))18Insert #T19select1,N'A',N'A1'union all20select2,N'A',N'A2'union all21select3,N'A',N'A3'union all22select4,N'B',N'B1'union all23select5,N'B',N'B2'24Go252627--I、Name相同ID最⼩的记录(推荐⽤1,2,3),⽅法3在SQl05时,效率⾼于1、228⽅法1:29Select*from #T a where not exists(select1from #T where Name= and ID<a.ID)3031⽅法2:32select a.*from #T a join (select min(ID)ID,Name from #T group by Name) b on = and a.ID=b.ID3334⽅法3:35select*from #T a where ID=(select min(ID) from #T where Name=)3637⽅法4:38select a.*from #T a join #T b on = and a.ID>=b.ID group by a.ID,,a.Memo having count(1)=13940⽅法5:41select*from #T a group by ID,Name,Memo having ID=(select min(ID)from #T where Name=)4243⽅法6:44select*from #T a where (select count(1) from #T where Name= and ID<a.ID)=04546⽅法7:47select*from #T a where ID=(select top1 ID from #T where Name= order by ID)4849⽅法8:50select*from #T a where ID!>all(select ID from #T where Name=)5152⽅法9(注:ID为唯⼀时可⽤):53select*from #T a where ID in(select min(ID) from #T group by Name)5455--SQL2005:5657⽅法10:58select ID,Name,Memo from (select*,min(ID)over(partition by Name) as MinID from #T a)T where ID=MinID5960⽅法11:6162select ID,Name,Memo from (select*,row_number()over(partition by Name order by ID) as MinID from #T a)T where MinID=1 6364⽣成结果:65/*66ID Name Memo67----------- ---- ----681 A A1694 B B17071(2 ⾏受影响)72*/737475--II、Name相同ID最⼤的记录,与min相反:76⽅法1:77Select*from #T a where not exists(select1from #T where Name= and ID>a.ID)7879⽅法2:80select a.*from #T a join (select max(ID)ID,Name from #T group by Name) b on = and a.ID=b.ID order by ID 8182⽅法3:83select*from #T a where ID=(select max(ID) from #T where Name=) order by ID8485⽅法4:86select a.*from #T a join #T b on = and a.ID<=b.ID group by a.ID,,a.Memo having count(1)=18788⽅法5:89select*from #T a group by ID,Name,Memo having ID=(select max(ID)from #T where Name=)9091⽅法6:92select*from #T a where (select count(1) from #T where Name= and ID>a.ID)=09394⽅法7:95select*from #T a where ID=(select top1 ID from #T where Name= order by ID desc)9697⽅法8:98select*from #T a where ID!<all(select ID from #T where Name=)99100⽅法9(注:ID为唯⼀时可⽤):101select*from #T a where ID in(select max(ID) from #T group by Name)102103--SQL2005:104105⽅法10:106select ID,Name,Memo from (select*,max(ID)over(partition by Name) as MinID from #T a)T where ID=MinID107108⽅法11:109select ID,Name,Memo from (select*,row_number()over(partition by Name order by ID desc) as MinID from #T a)T where MinID=1 110111⽣成结果2:112/*113ID Name Memo114----------- ---- ----1153 A A31165 B B2117118(2 ⾏受影响)119*/120121122123--2、删除重复记录有⼤⼩关系时,保留⼤或⼩其中⼀个记录124125126--> --> (Roy)⽣成測試數據127128if not object_id('Tempdb..#T') is null129drop table #T130Go131Create table #T([ID]int,[Name]nvarchar(1),[Memo]nvarchar(2))132Insert #T133select1,N'A',N'A1'union all134select2,N'A',N'A2'union all135select3,N'A',N'A3'union all136select4,N'B',N'B1'union all137select5,N'B',N'B2'138Go139140--I、Name相同ID最⼩的记录(推荐⽤1,2,3),保留最⼩⼀条141⽅法1:142delete a from #T a where exists(select1from #T where Name= and ID<a.ID)143144⽅法2:145delete a from #T a left join (select min(ID)ID,Name from #T group by Name) b on = and a.ID=b.ID where b.Id is null 146147⽅法3:148delete a from #T a where ID not in (select min(ID) from #T where Name=)149150⽅法4(注:ID为唯⼀时可⽤):151delete a from #T a where ID not in(select min(ID)from #T group by Name)152153⽅法5:154delete a from #T a where (select count(1) from #T where Name= and ID<a.ID)>0155156⽅法6:157delete a from #T a where ID<>(select top1 ID from #T where Name= order by ID)158159⽅法7:160delete a from #T a where ID>any(select ID from #T where Name=)161162163164select*from #T165166⽣成结果:167/*168ID Name Memo169----------- ---- ----1701 A A11714 B B1172173(2 ⾏受影响)174*/175176177--II、Name相同ID保留最⼤的⼀条记录:178179⽅法1:180delete a from #T a where exists(select1from #T where Name= and ID>a.ID)181182⽅法2:183delete a from #T a left join (select max(ID)ID,Name from #T group by Name) b on = and a.ID=b.ID where b.Id is null 184185⽅法3:186delete a from #T a where ID not in (select max(ID) from #T where Name=)187188⽅法4(注:ID为唯⼀时可⽤):189delete a from #T a where ID not in(select max(ID)from #T group by Name)190191⽅法5:192delete a from #T a where (select count(1) from #T where Name= and ID>a.ID)>0193194⽅法6:195delete a from #T a where ID<>(select top1 ID from #T where Name= order by ID desc)196197⽅法7:198delete a from #T a where ID<any(select ID from #T where Name=)199200201select*from #T202/*203ID Name Memo204----------- ---- ----2053 A A32065 B B2207208(2 ⾏受影响)209*/210211212213214215--3、删除重复记录没有⼤⼩关系时,处理重复值216217218--> --> (Roy)⽣成測試數據219220if not object_id('Tempdb..#T') is null221drop table #T222Go223Create table #T([Num]int,[Name]nvarchar(1))224Insert #T225select1,N'A'union all226select1,N'A'union all227select1,N'A'union all228select2,N'B'union all229select2,N'B'230Go231232⽅法1:233if object_id('Tempdb..#') is not null234drop table #235Select distinct*into # from #T--排除重复记录结果集⽣成临时表#236237truncate table #T--清空表238239insert #T select*from # --把临时表#插⼊到表#T中240241--查看结果242select*from #T243244/*245Num Name246----------- ----2471 A2482 B249250(2 ⾏受影响)251*/252253--重新执⾏测试数据后⽤⽅法2254⽅法2:255256alter table #T add ID int identity--新增标识列257go258delete a from #T a where exists(select1from #T where Num=a.Num and Name= and ID>a.ID)--只保留⼀条记录259go260alter table #T drop column ID--删除标识列261262--查看结果263select*from #T264265/*266Num Name267----------- ----2681 A2692 B270271(2 ⾏受影响)272273*/274275--重新执⾏测试数据后⽤⽅法3276⽅法3:277declare Roy_Cursor cursor local for278select count(1)-1,Num,Name from #T group by Num,Name having count(1)>1 279declare@con int,@Num int,@Name nvarchar(1)280open Roy_Cursor281fetch next from Roy_Cursor into@con,@Num,@Name282while@@Fetch_status=0283begin284set rowcount@con;285delete #T where Num=@Num and Name=@Name286set rowcount0;287fetch next from Roy_Cursor into@con,@Num,@Name288end289close Roy_Cursor290deallocate Roy_Cursor291292--查看结果293select*from #T294/*295Num Name296----------- ----2971 A2982 B299300(2 ⾏受影响)301*/删除重复数据保留最⼤id或最⼩id的SQL语句··。
sql语句查询重复的数据
sql语句查询重复的数据查找所有重复标题的记录:SELECT *FROM t_info aWHERE ((SELECT COUNT(*)FROM t_infoWHERE Title = a.Title) > 1)ORDER BY Title DESC⼀。
查找重复记录1。
查找全部重复记录Select * From 表 Where 重复字段 In (Select 重复字段 From 表 Group By 重复字段 Having Count(*)>1) 2。
过滤重复记录(只显⽰⼀条)Select * From HZT Where ID In (Select Max(ID) From HZT Group By Title)注:此处显⽰ID最⼤⼀条记录⼆。
删除重复记录1。
删除全部重复记录(慎⽤)Delete 表 Where 重复字段 In (Select 重复字段 From 表 Group By 重复字段 Having Count(*)>1)2。
保留⼀条(这个应该是⼤多数⼈所需要的 ^_^)Delete HZT Where ID Not In (Select Max(ID) From HZT Group By Title)注:此处保留ID最⼤⼀条记录1、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select * from peoplewhere peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1)2、删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowid最⼩的记录delete from peoplewhere 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 awhere (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)4、删除表中多余的重复记录(多个字段),只留有rowid最⼩的记录delete from vitae awhere (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 awhere (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)补充:有两个以上的重复记录,⼀是完全重复的记录,也即所有字段均重复的记录,⼆是部分关键字段重复的记录,⽐如Name字段重复,⽽其他字段不⼀定重复或都重复可以忽略。
SQL查询重复数据和清除重复数据
SQL查询重复数据和清除重复数据分类: SQL 2008-05-20 11:03 34086人阅读评论(1) 收藏举报sqlsqlserversunjoin选择重复,消除重复和选择出序列有例表:empemp_no name age001 Tom 17002 Sun 14003 Tom 15004 Tom 16要求:列出所有名字重复的人的记录(1)最直观的思路:要知道所有名字有重复人资料,首先必须知道哪个名字重复了:select name from emp group by name having count(*)>1所有名字重复人的记录是:select * from empwhere name in (select name from emp group by name having count(*)>1)(2)稍微再聪明一点,就会想到,如果对每个名字都和原表进行比较,大于2个人名字与这条记录相同的就是合格的,就有select * from emp where (select count(*) from emp e where=) >1注意一下这个>1,想下如果是 =1,如果是 =2 如果是>2 如果 e 是另外一张表而且是=0那结果就更好玩了:)这个过程是在判断工号为001的人的时候先取得001的名字()然后和原表的名字进行比较 注意e是emp的一个别名。
再稍微想得多一点,就会想到,如果有另外一个名字相同的人工号不与她他相同那么这条记录符合要求:select * from empwhere exists(select * from emp e where = ande.emp_no<>emp.emp_no)此思路的join写法:select emp.* from emp,emp ewhere = and emp.emp_no<>e.emp_no/* 这个语句较规范的 join 写法是select emp.* from emp inner join emp e on = and emp.emp_no<>e.emp_no但个人比较倾向于前一种写法,关键是更清晰 */b、有例表:empname ageTom 16Sun 14Tom 16Tom 16清除重复过滤掉所有多余的重复记录(1)我们知道distinct、group by 可以过滤重复,于是就有最直观的select distinct * from emp 或 select name,age from emp group by name,age获得需要的数据,如果可以使用临时表就有解法:select distinct * into #tmp from empdelete from empinsert into emp select * from #tmp(2)但是如果不可以使用临时表,那该怎么办?我们观察到我们没办法区分数据(物理位置不一样,对 SQL Server来说没有任何区别),思路自然是想办法把数据区分出来了,既然现在的所有的列都没办法区分数据,唯一的办法就是再加个列让它区分出来,加什么列好?最佳选择是identity列:alter table emp add chk int identity(1,1)表示例:name age chkTom 16 1Sun 14 2Tom 16 3Tom 16 4重复记录可以表示为:select * from emp where (select count(*) from emp e where=)>1要删除的是:delete from empwhere (select count(*) from emp e where = and e.chk>=emp.chk)>1再把添加的列删掉,出现结果。
教你几种在SQLServer中删除重复数据方法
教你⼏种在SQLServer中删除重复数据⽅法复制代码代码如下:declare @max integer,@id integerdeclare cur_rows cursor local for select 主字段,count(*) from 表名 group by 主字段 having count(*) > 1open cur_rowsfetch cur_rows into @id,@maxwhile @@fetch_status=0beginselect @max = @max -1set rowcount @maxdelete from 表名 where 主字段 = @idfetch cur_rows into @id,@maxendclose cur_rowsset rowcount 0有两个意义上的重复记录,⼀是完全重复的记录,也即所有字段均重复的记录,⼆是部分关键字段重复的记录,⽐如Name字段重复,⽽其他字段不⼀定重复或都重复可以忽略。
复制代码代码如下:select distinct * from tableName就可以得到⽆重复记录的结果集。
如果该表需要删除重复的记录(重复记录保留1条),可以按以下⽅法删除复制代码代码如下:select distinct * into #Tmp from tableNamedrop table tableNameselect * into tableName from #Tmpdrop table #Tmp发⽣这种重复的原因是表设计不周产⽣的,增加唯⼀索引列即可解决。
2、这类重复问题通常要求保留重复记录中的第⼀条记录,操作⽅法如下假设有重复的字段为Name,Address,要求得到这两个字段唯⼀的结果集复制代码代码如下:select identity(int,1,1) as autoID, * into #Tmp from tableNameselect min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoIDselect * from #Tmp where autoID in(select autoID from #tmp2)最后⼀个select即得到了Name,Address不重复的结果集(但多了⼀个autoID字段,实际写时可以写在select⼦句中省去此列)前段时间写的如何删除sql数据库中重复记录是针对sql数据库的,最近发现有⼈需求access数据库删除重复记录的语句,发上来与⼤家分享。
sql删除重复数据方法
sql删除重复数据方法在SQL中,可以使用多种方法删除重复数据。
以下是一些常见的方法:1.使用DISTINCT关键字:DISTINCT关键字用于从结果集中仅选择唯一的值。
可以将DISTINCT用于SELECT语句,以选择指定列中的唯一值。
例如,如果要删除表中name列中的重复数据,可以使用以下语句:```DELETE FROM table_name WHERE id NOT IN (SELECT MIN(id) FROM table_name GROUP BY name);```这将删除除具有最小ID值的记录外,表中所有name列的重复记录。
2.使用临时表:可以使用临时表来删除重复数据。
首先,创建一个临时表,将表中的数据插入到临时表中。
然后,从临时表中删除重复数据。
最后,将临时表中的数据重新插入到原始表中。
以下是一个使用临时表删除重复数据的例子:```--创建临时表CREATE TABLE temp_table AS SELECT DISTINCT * FROMoriginal_table;--清空原始表TRUNCATE TABLE original_table;--从临时表中重新插入数据到原始表INSERT INTO original_table SELECT * FROM temp_table;```请注意,上述示例省略了保持表结构的细节。
3.使用ROW_NUMBER(函数:ROW_NUMBER(函数为每个行分配一个唯一的数字。
可以使用该函数删除重复数据。
以下是一个使用ROW_NUMBER(函数删除重复数据的例子:```DELETEFROMSELECT column1, column2, column3, ROW_NUMBER( OVER (PARTITION BY column1, column2, column3 ORDER BY (SELECT 0)) AS rnFROM table_nametWHERE t.rn > 1;```上述示例按列column1、column2和column3进行分组,并按指定的顺序为每个组分配唯一的行号。
2008 sql 案例重复
2008 sql 案例重复2008年的SQL案例重复是一个常见的问题,这种情况在数据库管理中经常发生。
当数据表中存在重复的记录时,会对数据的准确性和性能产生负面影响。
因此,需要使用SQL语句来去除重复数据,以确保数据的完整性和一致性。
下面是一些常用的SQL语句,用于处理重复数据的案例:1. 去除重复行:```sqlSELECT DISTINCT * FROM table_name;```这条语句会返回表中的所有不重复的行。
2. 根据特定列去除重复行:```sqlSELECT DISTINCT column1, column2 FROM table_name;```这条语句会返回特定列(column1和column2)中的不重复的值。
3. 根据多个列去除重复行:```sqlSELECT DISTINCT column1, column2 FROM table_name;```这条语句会返回多个列(column1和column2)中的不重复的值。
4. 删除重复行:```sqlDELETE FROM table_name WHERE column_name IN (SELECT column_name FROM table_name GROUP BY column_name HAVING COUNT(*) > 1);```这条语句会删除表中所有重复的行,只保留一行。
5. 查找重复行:```sqlSELECT column_name, COUNT(*) FROM table_name GROUP BY column_name HAVING COUNT(*) > 1;```这条语句会返回表中所有重复的行及其重复的次数。
6. 将重复行合并为一行:```sqlSELECT column1, column2, GROUP_CONCAT(column3) FROM table_name GROUP BY column1, column2;```这条语句会将具有相同column1和column2值的多行合并为一行,并将合并后的column3值以逗号分隔的形式呈现。
一次SQL如何查重及去重的实战记录
⼀次SQL如何查重及去重的实战记录⽬录前⾔1.distinct2.groupby3.row_number窗⼝函数4.删除重复数据第⼀步:找出重复的数据第⼆步:删除重复的数据总结前⾔在使⽤SQL提数的时候,常会遇到表内有重复值的时候,就需要做去重,本⽂归类了常⽤⽅法。
1.distinct题⽬:现在运营需要查看⽤户来⾃于哪些学校,请从⽤户信息表中取出学校的去重数据⽰例:user_profilemysql>SELECT DISTINCT university FROM user_profile;根据⽰例,查询返回以下结果⼩贴⼠:SQL中关键词distinct去重:英语中distinct 代表独⼀⽆⼆的意思,他在SQL表⽰去重的意思:⽐如本题中university这⼀列出现了两次北京⼤学,使⽤distinct进⾏去重查询后,则北京⼤学只出现⼀次。
distinct 通常效率较低distinct 使⽤中,放在 select 后边,对后⾯所有的字段的值统⼀进⾏去重拓展:题⽬:现在运营需要查看⽤户的总数select count(distinct university) from user_profile;2.group by举个栗⼦,现有这样⼀张表 task备注:task_id: 任务id;order_id: 订单id;start_time: 开始时间注意:⼀个任务对应多条订单题⽬:列出任务总数根据⽰例,查询⽅法如下:第1步:列出 task_id 的所有唯⼀值(去重后的记录,null也是值)select task_idfrom Taskgroup by task_id;第⼆步:任务总数select count(task_id) task_numfrom (select task_idfrom Taskgroup by task_id) tmp;3.row_number 窗⼝函数举个栗⼦,现有这样⼀张表 task备注:task_id: 任务id;order_id: 订单id;start_time: 开始时间注意:⼀个任务对应多条订单题⽬:查询整个表重复的数据根据⽰例,查询⽅法如下:– 在⽀持窗⼝函数的 sql 中使⽤select count(case when rn=1 then task_id else null end) task_numfrom (select task_id, row_number() over (partition by task_id order by start_time) rnfrom Task) tmp;⼩贴⼠:MySQL8.0 中可以利⽤ ROW_NUMBER(),DENSE_RANK(),RANK() 三个窗⼝函数来实现排序需要注意的⼀点是 as 后的别名,千万不要与前⾯的函数名重名,否则会报错下⾯给出这三种函数实现排名的案例:–三条语句对于上⾯三种排名select xuehao,score, ROW_NUMBER() OVER(order by score desc) as row_r from scores_tb;select xuehao,score, DENSE_RANK() OVER(order by score desc) as dense_r from scores_tb;select xuehao,score, RANK() over(order by score desc) as r from scores_tb;– ⼀条语句也可以查询出不同排名SELECT xuehao,score,ROW_NUMBER() OVER w AS ‘row_r',DENSE_RANK() OVER w AS ‘dense_r',RANK() OVER w AS ‘r'FROM scores_tbWINDOW w AS (ORDER BY score desc);4.删除重复数据创建测试数据我们创建⼀个⼈员信息表并在⾥⾯插⼊⼀些重复的数据CREATE TABLE Person(id int auto_increment primary key comment ‘主键',Name VARCHAR(20) NULL,Age INT NULL,Address VARCHAR(20) NULL,Sex CHAR(2) NULL);INSERT INTO Person(ID,Name,Age,Address,Sex)VALUES( 1, ‘张三', 18, ‘北京路18号', ‘男' ),( 2, ‘李四', 19, ‘北京路29号', ‘男' ),( 3, ‘王五', 19, ‘南京路11号', ‘⼥' ),( 4, ‘张三', 18, ‘北京路18号', ‘男' ),( 5, ‘李四', 19, ‘北京路29号', ‘男' ),( 6, ‘张三', 18, ‘北京路18号', ‘男' ),( 7, ‘王五', 19, ‘南京路11号', ‘⼥' ),( 8, ‘马六', 18, ‘南京路19号', ‘⼥' );题⽬:数据库中存在重复记录,删除保留其中⼀条我们发现除了⾃增长ID不同以为,有⼏条其他字段都重复的数据出现第⼀步:找出重复的数据mysql>SELECT MAX(ID) ID,Name,Age,Address,SexFROM PersonGROUP BY Name,Age,Address,SexHAVING COUNT(1)>1⼩贴⼠:HAVING将分组后统计出来的数量⼤于1的数据⾏,就是我们要找的重复数据上⾯⽤Max函数或者Min函数均可,只是为了保证取出来的数据的唯⼀性。
mssql delete 语句
mssql delete 语句MSSQL是一种广泛使用的关系型数据库管理系统,DELETE语句是其中一种常用的数据操作语句,用于删除数据库中的数据。
下面将列举10个符合标题要求的MSSQL DELETE语句示例。
1. 删除表中的所有数据:DELETE FROM 表名;2. 删除表中满足条件的数据:DELETE FROM 表名 WHERE 条件;3. 删除表中重复的数据,只保留一条:DELETE FROM 表名WHERE 列名NOT IN (SELECT MIN(列名) FROM 表名 GROUP BY 列名);4. 删除表中满足多个条件的数据:DELETE FROM 表名 WHERE 条件1 AND 条件2;5. 删除表中满足某个条件的数据,并返回删除的行数:DELETE 表名 OUTPUT DELETED.* WHERE 条件;6. 删除表中指定行数的数据:DELETE TOP (N) FROM 表名;7. 删除表中满足条件的数据,并将删除的行存储到另一个表中:DELETE FROM 表名OUTPUT DELETED.* INTO 新表名WHERE 条件;8. 删除表中满足某个条件的数据,并将删除的行存储到一个变量中:DECLARE @变量名数据类型;DELETE FROM 表名 OUTPUT DELETED.* INTO @变量名 WHERE 条件;9. 删除表中的所有数据,并重置表的自增长ID:DELETE FROM 表名;DBCC CHECKIDENT('表名', RESEED, 0);10. 删除表中满足条件的数据,并将删除的行存储到一个临时表中:SELECT * INTO #临时表名 FROM 表名 WHERE 条件;DELETE FROM 表名 WHERE 条件;以上是10个符合要求的MSSQL DELETE语句示例。
这些语句可以用于删除数据库表中的数据,根据不同的条件进行删除操作,还可以将删除的数据存储到其他表或变量中。
sql去除重复的几种方法
sql去除重复的⼏种⽅法
所以⽤这样⼀句SQL就可以去掉重复项了:
select * from msg group by terminal_id;
SQL中distinct的⽤法(四种⽰例分析)
⽰例1
select distinct name from A
执⾏后结果如下:
⽰例2
select distinct name, id from A
执⾏后结果如下:
实际上是根据“name+id”来去重,distinct同时作⽤在了name和id上,这种⽅式Access和SQL Server同时⽀持。
⽰例3:统计
select count(distinct name) from A; --表中name去重后的数⽬, SQL Server⽀持,⽽Access不⽀持
select count(distinct name, id) from A; --SQL Server和Access都不⽀持
⽰例4
select id, distinct name from A; --会提⽰错误,因为distinct必须放在开头
其他
distinct语句中select显⽰的字段只能是distinct指定的字段,其他字段是不可能出现的。
例如,假如表A有“备注”列,如果想获取distinc name,以及对应的“备注”字段,想直接通过distinct是不可能实现的。
SQL中常见的三种去重方法
SQL中常见的三种去重⽅法在 MySQL 中通常是使⽤ distinct 或 group by⼦句,但在⽀持窗⼝函数的 sql(如Hive SQL、Oracle等等)中还可以使⽤ row_number 窗⼝函数进⾏去重。
举个栗⼦,现有这样⼀张表 task:备注:task_id: 任务id;order_id: 订单id;start_time: 开始时间注意:⼀个任务对应多条订单我们需要求出任务的总数量,因为 task_id 并⾮唯⼀的,所以需要去重:distinct-- 列出 task_id 的所有唯⼀值(去重后的记录)-- select distinct task_id-- from Task;-- 任务总数select count(distinct task_id) task_numfrom Task;distinct 通常效率较低。
它不适合⽤来展⽰去重后具体的值,⼀般与 count 配合⽤来计算条数。
distinct 使⽤中,放在 select 后边,对后⾯所有的字段的值统⼀进⾏去重。
⽐如distinct后⾯有两个字段,那么 1,1 和 1,2 这两条记录不是重复值。
group by-- 列出 task_id 的所有唯⼀值(去重后的记录,null也是值)-- select task_id-- from Task-- group by task_id;-- 任务总数select count(task_id) task_numfrom (select task_idfrom Taskgroup by task_id) tmp;row_numberrow_number 是窗⼝函数,语法如下:row_number() over (partition by <⽤于分组的字段名> order by <⽤于组内排序的字段名>)其中 partition by 部分可省略。
-- 在⽀持窗⼝函数的 sql 中使⽤select count(case when rn=1then task_id else null end) task_numfrom (select task_id, row_number() over (partition by task_id order by start_time) rnfrom Task) tmp;。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SQL删除重复数据
(2009-05-16 12:40:00)
转载
标签:
分类:一路辛酸---C#
sql删除
重复数据
delete
执行效率
it
重复的数据可能有这样两种情况,第一种时表中只有某些字段一样,第二种是两行记录完全一样。
一、对于部分字段重复数据的删除
先来谈谈如何查询重复的数据吧。
下面语句可以查询出那些数据是重复的:
select字段1,字段2,count(*) from 表名group by 字段1,字段2 having count(*) > 1
将上面的>号改为=号就可以查询出没有重复的数据了。
想要删除这些重复的数据,可以使用下面语句进行删除
delete from表名a where 字段1,字段2 in
(select 字段1,字段2,count(*) from 表名group by 字段1,字段2 having count(*) > 1)
上面的语句非常简单,就是将查询到的数据删除掉。
不过这种删除执行的效率非常低,对于大数据量来说,可能会将数据库吊死。
所以我建议先将查询到的重复的数据插入到一个临时表中,然后对进行删除,这样,执行删除的时候就不用再进行一次查询了。
如下:
CREATE TABLE临时表AS
(select 字段1,字段2,count(*) from 表名group by 字段1,字段2 having count(*) > 1) 上面这句话就是建立了临时表,并将查询到的数据插入其中。
下面就可以进行这样的删除操作了:
delete from 表名a where 字段1,字段2 in (select 字段1,字段2 from 临时表);
这种先建临时表再进行删除的操作要比直接用一条语句进行删除要高效得多。
这个时候,大家可能会跳出来说,什么?你叫我们执行这种语句,那不是把所有重复的全都删除吗?而我们想保留重复数据中最新的一条记录啊!大家不要急,下面我就讲一下如何进行这种操作。
在oracle中,有个隐藏了自动rowid,里面给每条记录一个唯一的rowid,我们如果想保留最新的一条记录,我们就可以利用这个字段,保留重复数据中rowid最大的一条记录就可以了。
下面是查询重复数据的一个例子:
select a.rowid,a.* from表名a
where a.rowid !=
(
select max(b.rowid) from 表名b
where a.字段1 = b.字段1 and
a.字段2 =
b.字段2
)
下面我就来讲解一下,上面括号中的语句是查询出重复数据中rowid最大的一条记录。
而外面就是查询出除了rowid最大之外的其他重复的数据了。
由此,我们要删除重复数据,只保留最新的一条数据,就可以这样写了:
delete from 表名a
where a.rowid !=
(
select max(b.rowid) from 表名b
where a.字段1 = b.字段1 and
a.字段2 =
b.字段2
)
随便说一下,上面语句的执行效率是很低的,可以考虑建立临时表,讲需要判断重复的字段、rowid插入临时表中,然后删除的时候在进行比较。
create table 临时表as
select a.字段1,a.字段2,MAX(a.ROWID) dataid from 正式表a GROUP BY a.字段1,a.字段2;
delete from 表名a
where a.rowid !=
(
select b.dataid from 临时表b
where a.字段1 = b.字段1 and
a.字段2 =
b.字段2
);
commit;
二、对于完全重复记录的删除
对于表中两行记录完全一样的情况,可以用下面语句获取到去掉重复数据后的记录:select distinct * from 表名
可以将查询的记录放到临时表中,然后再将原来的表记录删除,最后将临时表的数据导回原来的表中。
如下:
CREATE TABLE 临时表AS (select distinct * from 表名);
drop table 正式表;
insert into 正式表(select * from 临时表);
drop table 临时表;
如果想删除一个表的重复数据,可以先建一个临时表,将去掉重复数据后的数据导入到临时表,然后在从临时表将数据导入正式表中,如下:
INSERT INTO t_table_bak
select distinct * from t_table;。