MSSQLSERVER数据库- SQL删除重复数据的五种方式

  删除重复的数据,在平时的工作中还是会和碰到的,感觉挺有用,从网上摘录的,记在这里,以备需要时查阅 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
--方法一,IN方式,适合2000/2005/2008,6728 毫秒
 
 DELETE [student_L]
 
 WHERE  id NOT IN ( SELECT  MAX(id)--min(id)
                    FROM    [student_L]
                    GROUP BY [stuid], [stuname], [Birthday], [AreaOrganID] )
 
<br>/*
 
   SQL Server 分析和编译时间:
   CPU 时间= 20 毫秒,占用时间= 20 毫秒。
表'student_L'。扫描计数2001,逻辑读取30014 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
表'Worktable'。扫描计数1,逻辑读取2020 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
 
 SQL Server 执行时间:
 CPU 时间= 6719 毫秒,占用时间= 6728 毫秒。
 (1000 行受影响)
 
*/
 
                    
 
 --方法二,CTE方式,适合2005/2008,30 毫秒
 WITH   dstudent
          AS (
               SELECT   id,
                        ROW_NUMBER() OVER ( PARTITION BY [stuid], [stuname],
                                            [Birthday], [AreaOrganID] ORDER BY GETDATE() ) pid
               FROM     [student_L]
             )
 
    DELETE  dstudent
    WHERE   id NOT IN ( SELECT  id
                        FROM    dstudent
                        WHERE   pid = 1 )
 
 
 /*
 
 SQL Server 分析和编译时间:
   CPU 时间= 12 毫秒,占用时间= 12 毫秒。
表'student_L'。扫描计数4,逻辑读取2056 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
表'Worktable'。扫描计数1,逻辑读取2020 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
 
  
 SQL Server 执行时间:
 CPU 时间= 32 毫秒,占用时间= 30 毫秒。
(1000 行受影响)
 */
 
   
 
    
 
 --方法三, LEFT JOIN方式,适合2000/2005/2008,7379 毫秒   
 
 DELETE stu
 FROM   [student_L] stu
 LEFT JOIN (
             SELECT ID = MAX(id)
             FROM   [student_L]
             GROUP BY [stuid], [stuname], [Birthday], [AreaOrganID]
           ) S ON stu.id = s.id
 WHERE  s.id IS NULL
 
                  
 
 /*
 
 SQL Server 分析和编译时间:
 CPU 时间= 10 毫秒,占用时间= 10 毫秒。
表'student_L'。扫描计数2001,逻辑读取30014 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
表'Worktable'。扫描计数0,逻辑读取0 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
 
  
 SQL Server 执行时间:
  CPU 时间= 7375 毫秒,占用时间= 7379 毫秒。
 (1000 行受影响)
 
 */  
 
      
 
  --方法四,游标方式, 适合2000/2005/2008,833毫秒
 DECLARE @d DATETIME
 SET @d = GETDATE()
 
   --Script.Start
 
   ---------------------------------------------------------------------------------------------
 
 DECLARE @id INT
 DECLARE @stuid INT
 DECLARE @stuname VARCHAR(50)
 DECLARE @Birthday VARCHAR(10)
 DECLARE @AreaOrganID INT 
 DECLARE @prestuid INT
 DECLARE @prestuname VARCHAR(50)
 DECLARE @preBirthday VARCHAR(10)
 DECLARE @preAreaOrganID INT
 
  
 
 DECLARE cur CURSOR
 
 FOR
    SELECT  ID, [stuid], [stuname], [Birthday], [AreaOrganID]
    FROM    [student_L]
    ORDER BY [stuid], [stuname], [Birthday], [AreaOrganID]
 
 
 OPEN cur
 FETCH NEXT FROM cur INTO @id, @stuid, @stuname, @Birthday, @AreaOrganID
 
  WHILE @@FETCH_STATUS = 0
    BEGIN
 
        IF ( @stuid = @prestuid )
            AND ( @stuname = @prestuname )
            AND ( @Birthday = @preBirthday )
            AND ( @AreaOrganID = preAreaOrganID )
 
            BEGIN
                DELETE  [student_L]
                WHERE   id = @id
            END 
 
        SELECT  @prestuid = @stuid, @prestuname = @stuname,
                @preBirthday = @Birthday, @preAreaOrganID = @AreaOrganID 
 
        FETCH NEXT FROM cur INTO @id, @stuid, @stuname, @Birthday,
            @ArerOrganID
 
    END
 
  
 CLOSE cur
 DEALLOCATE cur
 
  
  ---------------------------------------------------------------------------------------------
 
  --Script.End
 
 PRINT DATEDIFF(ms, @d, GETDATE()) 
 
      
 --方法五,中间表方式, 适合/2005/2008 ,39 毫秒。
 
 SELECT (
          SELECT TOP 1
                    id
          FROM      student_l a
          WHERE     1 = 1
                    AND a.stuid = b.stuid
                    AND a.[stuname] = b.[stuname]
                    AND a.[Birthday] = b.[Birthday]
                    AND a.[AreaOrganID] = b.[AreaOrganID]
        ) id, [stuid], [stuname], [Birthday], [AreaOrganID]
 
 INTO   student_l1
 FROM   student_l b
 DROP TABLE student_l
 
             
 EXEC sp_rename 'dbo.student_l1', 'student_l';
 
 /*
 
  
 
SQL Server 分析和编译时间:
   CPU 时间= 0 毫秒,占用时间= 3 毫秒。
表'Worktable'。扫描计数2000,逻辑读取8067 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
表'student_l'。扫描计数2,逻辑读取22 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次
 
 SQL Server 执行时间:
  CPU 时间= 31 毫秒,占用时间= 39 毫秒。
 
(2000 行受影响)
 */

 

 

posted @   春天又来了  阅读(606)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示