T-SQL Recipes之删除重复行
准备基础数据
(1)创建辅助表,方便以后倾向于Set-base方式解决问题
-- Creating and Populating the Nums Auxiliary Table
SET NOCOUNT ON;
IF OBJECT_ID('dbo.Nums', 'U') IS NOT NULL
DROP TABLE dbo.Nums; CREATE TABLE dbo.Nums(n INT NOT NULL PRIMARY KEY); DECLARE @max AS INT ,
@rc AS INT; SET @max = 1000000;
SET @rc = 1; INSERT INTO dbo.Nums
( n )
VALUES ( 1 );
WHILE @rc * 2 <= @max
BEGIN
INSERT INTO dbo.Nums
( n )
SELECT n + @rc
FROM dbo.Nums;
SET @rc = @rc * 2;
END
INSERT INTO dbo.Nums
( n
)
SELECT n + @rc
FROM dbo.Nums
WHERE n + @rc <= @max;
GO
(2) 准备一些重复数据,这里使用AdventureWorks2014
PS:造成重复数据的原因有很多种,比如没有设置主键,批量导入的时候可能被执行了多次,归根到底还是人为原因。
USE AdventureWorks2014;
GO IF OBJECT_ID('dbo.OrdersDups') IS NOT NULL
BEGIN
DROP TABLE dbo.OrdersDups;
END SELECT SalesOrderID ,
CustomerID ,
SalesPersonID ,
OrderDate
INTO dbo.OrdersDups
FROM Sales.SalesOrderHeader
CROSS JOIN dbo.Nums
WHERE n <= 3;
如图,我们有了许多重复数据,现在就要考虑如何去重了。

解决方案
这里小陈提供三种去重方案,每一种方案都有相似性,也有独特之处。
1. 使用ROW_NUMBER() 函数去重,这种方式适合于比例小的重复数据。
USE AdventureWorks2014;
GO WITH Dups AS (
SELECT SalesOrderID ,
CustomerID ,
SalesPersonID ,
OrderDate ,
ROW_NUMBER() OVER ( PARTITION BY SalesOrderID ORDER BY ( SELECT0) ) AS rn
FROM dbo.OrdersDups) DELETE FROM Dups
WHERE rn > 1;
在未删除之前,先看一下前10行的数据是什么模样.

2. 使用ROW_NUMBER() + RANK() 函数去重,这种方式跟第一种类似,也是适合比例小的重复数据。
USE AdventureWorks2014;
GO WITH Dups AS (
SELECT SalesOrderID ,
CustomerID ,
SalesPersonID ,
OrderDate ,
ROW_NUMBER() OVER ( PARTITION BY SalesOrderID ORDER BY ( SELECT 0) ) AS rn,
RANK() OVER(PARTITION BY SalesOrderID ORDER BY (SELECT 0)) AS rnk
FROM dbo.OrdersDups) DELETE FROM Dups
WHERE rn > 1;

3. 删除大量的重复行时,会导致日志行为,最终DELETE会执行的很慢。所以这里推荐的做法是复制唯一行到新表,减少日志操作。然后移除老表,把新表的名字重命名为老表。
USE AdventureWorks2014;
GO WITH Dups AS (
SELECT SalesOrderID ,
CustomerID ,
SalesPersonID ,
OrderDate ,
ROW_NUMBER() OVER ( PARTITION BY SalesOrderID ORDER BY ( SELECT 0) ) AS rn
FROM dbo.OrdersDups) SELECT
SalesOrderID ,
CustomerID ,
SalesPersonID ,
OrderDate
INTO dbo.OrdersDupsTmp
FROM Dups
WHERE rn = 1; DROP TABLE dbo.OrdersDups; EXEC sp_rename 'dbo.OrdersDupsTmp', 'OrdersDups';
总结
这篇主要讲述如何去重,作为T-SQL私房菜的开篇,也是作为学习T-SQL的笔记——记述常见问题的解决方案。
如何哪位看官对T-SQL解决常见问题有什么好的解决方案也可以提出来,小陈争取在T-SQL私房菜系列中做一个汇总,也方便以后遇到类似的问题时直接在这里借用了。
当然内功心法还是记在心里面最好,这也是应随了老话:烂笔头胜过好记性。
T-SQL Recipes之删除重复行的更多相关文章
- SQL Server删除重复行的6个方法
SQL Server删除重复行是我们最常见的操作之一,下面就为您介绍六种适合不同情况的SQL Server删除重复行的方法,供您参考. 1.如果有ID字段,就是具有唯一性的字段 delect ta ...
- SQL查找删除重复行
本文讲述如何查找数据库里重复的行.这是初学者十分普遍遇到的问题.方法也很简单.这个问题还可以有其他演变,例如,如何查找“两字段重复的行”(#mysql IRC 频道问到的问题) 如何查找重复行 第一步 ...
- Oracle删除重复行
Oracle删除重复行 分类: ORACLE2010-12-12 17:10 423人阅读 评论(0) 收藏 举报 oracletabledeleteintegerinsert.net 查询及删除重复 ...
- SqlServer_删除重复行只保留一条记录
前提:相同的数据重复往数据库写入,导致存在仅主键Id不同的重复数据,现在需要去除重复数据,仅保留重复数据中Id最大的一条 思路: 1.找出存在重复数据的记录,并取重复数据中最大的Id值 2.删 ...
- linux用命令删除重复行
文本处理时,经常要删除重复行,下面是三种方法 第一,用sort+uniq,注意,单纯uniq是不行的. sort -n test.txt | uniq 第二,用sort+awk命令,注意,单纯awk同 ...
- Sublime文本排序&查找重复行&删除重复行
排序 按F9或者选择菜单:Edit > Sort Lines,对每行文本进行排序 查找重复行 排序好后,按Ctrl+F,调出查找面板 查找字符串: ^(.+)$[\r\n](^\1$[\r\n] ...
- editplus批量删除重复行(编辑-删除-删除重复行)
editplus快速删除重复数据 多行文本,有些行的文字或数据是重复的,该怎么删除重复部分,只留下不重复的部分?很多人对这个问题感到无比头疼,Editplus同样能快速帮你删除数据. 那么,editp ...
- UE如何去除重复行,删除重复行
1 如图所示,原理一个文本文档有两千多行,但是有大量的重复 2 使用UE的排序功能,有删除重复行的选项. 3 处理之后只剩下不到两百行了.
- Linux删除重复行
本文转自http://blog.csdn.net/ithomer/article/details/6926325 文本处理时,经常要删除重复行,下面是三种方法 第一,用sort+uniq,注意,单纯u ...
随机推荐
- Arcgis 10.1安装
来源http://download.csdn.net/detail/l_j_kin/7310665#comment 测试有效,存着备用,转过来不自己写了 安装desktop 打开“注册机”,功能选择a ...
- 浅谈 PHP 与手机 APP 开发(API 接口开发) -- 转载
转载自:http://www.thinkphp.cn/topic/5023.html 这个帖子写给不太了解PHP与API开发的人 一.先简单回答两个问题: 1.PHP 可以开发客户端? 答:不可以,因 ...
- 精选9个值得学习的 HTML5 效果【附源码】
这里精选了一组很酷的 HTML5 效果.HTML5 是现 Web 开发领域的热点, 拥有很多让人期待已久的新特性,特别是在移动端,Web 开发人员可以借助 HTML5 强大功能轻松制作各种交互性强.效 ...
- 错误 Metadata file 'C:\Common\bin\Debug\Common.dll' could not be found
一个通用方法de类库/总是报这个错误/很明显就是没有成功生成程序集... 但是就是找不到哪里的错误!!!! 如果是代码写错的话,可能会直接提示在哪个文件中哪行代码写错了,然后dll生成不了,但是这个错 ...
- 用jsp的application写一个记录用户登陆网站的数量
</head><body><%int i = 0;Object number = application.getAttribute("num");if ...
- Chrome 用户数据配置文件夹保存路径在哪?(Mac OS X/Windows/Linux)
在重装系统之前都想要对 Chrome 中的数据进行备份,以能够在重装系统后恢复这些数据.但是除了一些玩 Chrome 很长时间的用户,鲜有人知道 Chrome 的用户数据到底保存在什么地方.如果你也有 ...
- Linux线程同步:条件变量
条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用.使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化.一旦其它 ...
- 非常简单的升级phpnow自带的php版本到5.3的方法
下载PHP5.3 下载地址百度一下“PHP5.3下载”就有很多网站提供下载的,也可以去官网下载最新的,记得下载ZIP压缩的噢 2 解压与命名 将下载的PHP5.3压缩包解压至phpnow的安装目录,命 ...
- [BZOJ2391]Cirno的忧郁
[BZOJ2391]Cirno的忧郁 试题描述 Cirno闲着无事的时候喜欢冰冻青蛙. Cirno每次从雾之湖中固定的n个结点中选出一些点构成一个简单多边形,Cirno运用自己的能力能将此多边形内所有 ...
- Java 调用 C++ (Java 调用 dll)康哥手把手教你
摘要: 本文原创,转载请注明地址 http://www.cnblogs.com/baokang/p/4979243.html 因为要做点图形处理的项目,需要在Java中调用dll库,所以开发的第一步是 ...