`

联合主键---去重复记录的方法

sql 
阅读更多


方法1、
就是将三个字段连接起来作为主键,进行数据是否重复的判断。这里值得注意的是某列的值可能为空,所以要赋一个空字符串过去:
select * from t1 where nvl(col1,'')|| nvl(col2,'')|| col3 not in (select col1||col2||col3 from t2)
方法2、
统计多表联合查询 去重复记录的方法
两表结构不一样,或者一样的,多个表结合起来查询的,都可以
1. --> 生成测试数据表:a
2.
3. IF NOT OBJECT_ID('[a]') IS NULL
4. DROP TABLE [a]
5. GO
6. CREATE TABLE [a]([id] INT,[name] NVARCHAR(10),[parentid] INT)
7. INSERT [a]
8. SELECT 1,'area',0 UNION ALL
9. SELECT 2,'category',0 UNION ALL
10. SELECT 3,'north',1 UNION ALL
11. SELECT 4,'south',1 UNION ALL
12. SELECT 5,'Shanghai',4 UNION ALL
13. SELECT 6,'Beijing',3 UNION ALL
14. SELECT 7,'pudong',5 UNION ALL
15. SELECT 8,'xuhui',5 UNION ALL
16. SELECT 9,'chaoyang',6 UNION ALL
17. SELECT 10,'desk',2 UNION ALL
18. SELECT 11,'chair',2 UNION ALL
19. SELECT 12,'bed',2
20. GO
21.
22. --> 生成测试数据表:b
23.
24. IF NOT OBJECT_ID('[b]') IS NULL
25. DROP TABLE [b]
26. GO
27. CREATE TABLE [b]([id] INT,[area] INT,[city] INT,[district] NVARCHAR(10))
28. INSERT [b]
29. SELECT 1,4,5,'pudong' UNION ALL
30. SELECT 2,4,5,'xuhui' UNION ALL
31. SELECT 3,4,6,'chaoyang'
32. GO
33. --> 生成测试数据表:c
34.
35. IF NOT OBJECT_ID('[c]') IS NULL
36. DROP TABLE [c]
37. GO
38. CREATE TABLE [c]([id] INT,[category] INT,[area] INT,[city] INT,[district] INT)
39. INSERT [c]
40. SELECT 1,10,4,5,7 UNION ALL
41. SELECT 2,10,4,5,7 UNION ALL
42. SELECT 3,11,4,5,8 UNION ALL
43. SELECT 4,11,3,6,9 UNION ALL
44. SELECT 5,10,3,6,9
45. GO
46.
47. -->SQL查询如下:
48. --SELECT * FROM [a]
49. --SELECT * FROM [b]
50. --SELECT * FROM [c]
51.
52. -->SQL查询如下:
53. select a0.name area,
54. a1.name city,
55. a2.name district,
56. '' address,
57. MAX(case a3.name when 'desk' then 数量 else 0 end) 桌子数量,
58. MAX(case a3.name when 'chair' then 数量 else 0 end) 椅子数量,
59. MAX(case a3.name when 'bed' then 数量 else 0 end) 床数量
60. from (
61. select category,area,city,[district],COUNT(1) 数量
62. from c
63. group by category,area,city,[district]
64. ) c
65. join a a0 on a0.id=c.area
66. join a a1 on a1.id=c.[city]
67. join a a2 on a2.id=c.district
68. join a a3 on a3.id=c.category
69. left join b on b.area=c.area and c.city=b.city
70. group by a0.name,a1.name,a2.name
71. /*
72. area city district address 桌子数量 椅子数量 床数量
73. ---------- ---------- ---------- ------- ----------- ----------- -----------
74. north Beijing chaoyang 1 1 0
75. south Shanghai pudong 2 0 0
76. south Shanghai xuhui 0 1 0
77.
78. (3 行受影响)
79. */
1. --处理表重复记录(查询和删除)
2. /******************************************************************************************************************************************************
3. 1、Num、Name相同的重复值记录,没有大小关系只保留一条
4. 2、Name相同,ID有大小关系时,保留大或小其中一个记录
5. 整理人:中国风(Roy)
6.
7. 日期:2008.06.06
8. ******************************************************************************************************************************************************/
9.
10. --1、用于查询重复处理记录(如果列没有大小关系时2000用生成自增列和临时表处理,SQL2005用row_number函数处理)
11.
12. --> --> (Roy)生成測試數據
13.
14. if not object_id('Tempdb..#T') is null
15. drop table #T
16. Go
17. Create table #T([ID] int,[Name] nvarchar(1),[Memo] nvarchar(2))
18. Insert #T
19. select 1,N'A',N'A1' union all
20. select 2,N'A',N'A2' union all
21. select 3,N'A',N'A3' union all
22. select 4,N'B',N'B1' union all
23. select 5,N'B',N'B2'
24. Go
25.
26.
27. --I、Name相同ID最小的记录(推荐用1,2,3),方法3在SQl05时,效率高于1、2
28. 方法1:
29. Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID<a.ID)
30.
31. 方法2:
32. select a.* from #T a join (select min(ID)ID,Name from #T group by Name) b on a.Name=b.Name and a.ID=b.ID
33.
34. 方法3:
35. select * from #T a where ID=(select min(ID) from #T where Name=a.Name)
36.
37. 方法4:
38. select a.* from #T a join #T b on a.Name=b.Name and a.ID>=b.ID group by a.ID,a.Name,a.Memo having count(1)=1
39.
40. 方法5:
41. select * from #T a group by ID,Name,Memo having ID=(select min(ID)from #T where Name=a.Name)
42.
43. 方法6:
44. select * from #T a where (select count(1) from #T where Name=a.Name and ID<a.ID)=0
45.
46. 方法7:
47. select * from #T a where ID=(select top 1 ID from #T where Name=a.name order by ID)
48.
49. 方法8:
50. select * from #T a where ID!>all(select ID from #T where Name=a.Name)
51.
52. 方法9(注:ID为唯一时可用):
53. select * from #T a where ID in(select min(ID) from #T group by Name)
54.
55. --SQL2005:
56.
57. 方法10:
58. select ID,Name,Memo from (select *,min(ID)over(partition by Name) as MinID from #T a)T where ID=MinID
59.
60. 方法11:
61.
62. select ID,Name,Memo from (select *,row_number()over(partition by Name order by ID) as MinID from #T a)T where MinID=1
63.
64. 生成结果:
65. /*
66. ID Name Memo
67. ----------- ---- ----
68. 1 A A1
69. 4 B B1
70.
71. (2 行受影响)
72. */
73.
74.
75. --II、Name相同ID最大的记录,与min相反:
76. 方法1:
77. Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID>a.ID)
78.
79. 方法2:
80. select a.* from #T a join (select max(ID)ID,Name from #T group by Name) b on a.Name=b.Name and a.ID=b.ID order by ID
81.
82. 方法3:
83. select * from #T a where ID=(select max(ID) from #T where Name=a.Name) order by ID
84.
85. 方法4:
86. select a.* from #T a join #T b on a.Name=b.Name and a.ID<=b.ID group by a.ID,a.Name,a.Memo having count(1)=1
87.
88. 方法5:
89. select * from #T a group by ID,Name,Memo having ID=(select max(ID)from #T where Name=a.Name)
90.
91. 方法6:
92. select * from #T a where (select count(1) from #T where Name=a.Name and ID>a.ID)=0
93.
94. 方法7:
95. select * from #T a where ID=(select top 1 ID from #T where Name=a.name order by ID desc)
96.
97. 方法8:
98. select * from #T a where ID!<all(select ID from #T where Name=a.Name)
99.
100. 方法9(注:ID为唯一时可用):
101. select * from #T a where ID in(select max(ID) from #T group by Name)
102.
103. --SQL2005:
104.
105. 方法10:
106. select ID,Name,Memo from (select *,max(ID)over(partition by Name) as MinID from #T a)T where ID=MinID
107.
108. 方法11:
109. select ID,Name,Memo from (select *,row_number()over(partition by Name order by ID desc) as MinID from #T a)T where MinID=1
110.
111. 生成结果2:
112. /*
113. ID Name Memo
114. ----------- ---- ----
115. 3 A A3
116. 5 B B2
117.
118. (2 行受影响)
119. */
1. --分组取其中某字段最小,去重复
2. if object_id('[tb]') is not null drop table [tb]
3. go
4. create table [tb]([EID] varchar(2),[OID] varchar(2),[Value] int)
5. insert [tb]
6. select 'E1','O1',4 union all
7. select 'E2','O2',16 union all
8. select 'E3','O1',5 union all
9. select 'E4','O2',8 union all
10. select 'E5','O1',3 union all
11. select 'E6','O3',9
12.
13. select t1.* from tb t1
14. where EID = (
15. select top 1 t2. EID from tb t2
16. where t2.Value = (
17. select min(t3.Value) from tb t3
18. where t2.EID=t3.EID
19. ) and t1.OID=t2.OID
20. )
21. and t1.EID in ('E1','E2','E4')
1. --按某一字段分组取最大(小)值所在行的数据
2. --(爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 2007-10-23于浙江杭州)
3. /*
4. 数据如下:
5. name val memo
6. a 2 a2(a的第二个值)
7. a 1 a1--a的第一个值
8. a 3 a3:a的第三个值
9. b 1 b1--b的第一个值
10. b 3 b3:b的第三个值
11. b 2 b2b2b2b2
12. b 4 b4b4
13. b 5 b5b5b5b5b5
14. */
15. --创建表并插入数据:
16. create table tb(name varchar(10),val int,memo varchar(20))
17. insert into tb values('a', 2, 'a2(a的第二个值)')
18. insert into tb values('a', 1, 'a1--a的第一个值')
19. insert into tb values('a', 3, 'a3:a的第三个值')
20. insert into tb values('b', 1, 'b1--b的第一个值')
21. insert into tb values('b', 3, 'b3:b的第三个值')
22. insert into tb values('b', 2, 'b2b2b2b2')
23. insert into tb values('b', 4, 'b4b4')
24. insert into tb values('b', 5, 'b5b5b5b5b5')
25. go
26.
27. --一、按name分组取val最大的值所在行的数据。
28. --方法1:
29. select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name
30. --方法2:
31. select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val)
32. --方法3:
33. select a.* from tb a,(select name,max(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
34. --方法4:
35. select a.* from tb a inner join (select name , max(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
36. --方法5
37. select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name
38. /*
39. name val memo
40. ---------- ----------- --------------------
41. a 3 a3:a的第三个值
42. b 5 b5b5b5b5b5
43. */
44.
45. --二、按name分组取val最小的值所在行的数据。
46. --方法1:
47. select a.* from tb a where val = (select min(val) from tb where name = a.name) order by a.name
48. --方法2:
49. select a.* from tb a where not exists(select 1 from tb where name = a.name and val < a.val)
50. --方法3:
51. select a.* from tb a,(select name,min(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
52. --方法4:
53. select a.* from tb a inner join (select name , min(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
54. --方法5
55. select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val < a.val) order by a.name
56. /*
57. name val memo
58. ---------- ----------- --------------------
59. a 1 a1--a的第一个值
60. b 1 b1--b的第一个值
61. */
62.
63. --三、按name分组取第一次出现的行所在的数据。
64. select a.* from tb a where val = (select top 1 val from tb where name = a.name) order by a.name
65. /*
66. name val memo
67. ---------- ----------- --------------------
68. a 2 a2(a的第二个值)
69. b 1 b1--b的第一个值
70. */
71.
72. --四、按name分组随机取一条数据。
73. select a.* from tb a where val = (select top 1 val from tb where name = a.name order by newid()) order by a.name
74. /*
75. name val memo
76. ---------- ----------- --------------------
77. a 1 a1--a的第一个值
78. b 5 b5b5b5b5b5
79. */
80.
81. --五、按name分组取最小的两个(N个)val
82. select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.val
83. select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val
84. select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name,a.val
85. /*
86. name val memo
87. ---------- ----------- --------------------
88. a 1 a1--a的第一个值
89. a 2 a2(a的第二个值)
90. b 1 b1--b的第一个值
91. b 2 b2b2b2b2
92. */
93.
94. --六、按name分组取最大的两个(N个)val
95. select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val
96. select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val
97. select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name , a.val
98. /*
99. name val memo
100. ---------- ----------- --------------------
101. a 2 a2(a的第二个值)
102. a 3 a3:a的第三个值
103. b 4 b4b4
104. b 5 b5b5b5b5b5
105. */
106. --七,如果整行数据有重复,所有的列都相同。
107. /*
108. 数据如下:
109. name val memo
110. a 2 a2(a的第二个值)
111. a 1 a1--a的第一个值
112. a 1 a1--a的第一个值
113. a 3 a3:a的第三个值
114. a 3 a3:a的第三个值
115. b 1 b1--b的第一个值
116. b 3 b3:b的第三个值
117. b 2 b2b2b2b2
118. b 4 b4b4
119. b 5 b5b5b5b5b5
120. */
121. --在sql server 2000中只能用一个临时表来解决,生成一个自增列,先对val取最大或最小,然后再通过自增列来取数据。
122. --创建表并插入数据:
123. create table tb(name varchar(10),val int,memo varchar(20))
124. insert into tb values('a', 2, 'a2(a的第二个值)')
125. insert into tb values('a', 1, 'a1--a的第一个值')
126. insert into tb values('a', 1, 'a1--a的第一个值')
127. insert into tb values('a', 3, 'a3:a的第三个值')
128. insert into tb values('a', 3, 'a3:a的第三个值')
129. insert into tb values('b', 1, 'b1--b的第一个值')
130. insert into tb values('b', 3, 'b3:b的第三个值')
131. insert into tb values('b', 2, 'b2b2b2b2')
132. insert into tb values('b', 4, 'b4b4')
133. insert into tb values('b', 5, 'b5b5b5b5b5')
134. go
135.
136. select * , px = identity(int,1,1) into tmp from tb
137.
138. select m.name,m.val,m.memo from
139. (
140. select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
141. ) m where px = (select min(px) from
142. (
143. select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
144. ) n where n.name = m.name)
145.
146. drop table tb,tmp
147.
148. /*
149. name val memo
150. ---------- ----------- --------------------
151. a 1 a1--a的第一个值
152. b 1 b1--b的第一个值
153.
154. (2 行受影响)
155. */
156. --在sql server 2005中可以使用row_number函数,不需要使用临时表。
157. --创建表并插入数据:
158. create table tb(name varchar(10),val int,memo varchar(20))
159. insert into tb values('a', 2, 'a2(a的第二个值)')
160. insert into tb values('a', 1, 'a1--a的第一个值')
161. insert into tb values('a', 1, 'a1--a的第一个值')
162. insert into tb values('a', 3, 'a3:a的第三个值')
163. insert into tb values('a', 3, 'a3:a的第三个值')
164. insert into tb values('b', 1, 'b1--b的第一个值')
165. insert into tb values('b', 3, 'b3:b的第三个值')
166. insert into tb values('b', 2, 'b2b2b2b2')
167. insert into tb values('b', 4, 'b4b4')
168. insert into tb values('b', 5, 'b5b5b5b5b5')
169. go
170.
171. select m.name,m.val,m.memo from
172. (
173. select * , px = row_number() over(order by name , val) from tb
174. ) m where px = (select min(px) from
175. (
176. select * , px = row_number() over(order by name , val) from tb
177. ) n where n.name = m.name)
178.
179. drop table tb
180.
181. /*
182. name val memo
183. ---------- ----------- --------------------
184. a 1 a1--a的第一个值
185. b 1 b1--b的第一个值
186.
187. (2 行受影响)
188. */
分享到:
评论

相关推荐

    精髓Oralcle讲课笔记

    --将与这两个字段都重复的值去掉 10、select * from emp where deptno=10; --(条件过滤查询) 11、select * from emp where empno &gt; 10; --大于 过滤判断 12、select * from emp where empno &lt;&gt; 10 --不等于 ...

    MYSQL 建表约束

    **以下所有约束状态均能用describe查询 1、主键约束: ...**②方法二:联合主键,只要主键加起来不重复就可以。** Create table user2( Id int, Name varchar(20), Password varchar(20), Primary key(i

    SQL语法大全

    4. 记录集对象的方法: rs.movenext 将记录指针从当前的位置向下移一行 rs.moveprevious 将记录指针从当前的位置向上移一行 rs.movefirst 将记录指针移到数据表第一行 rs.movelast 将记录指针移到数据表最后一行 rs...

    Access 2000数据库系统设计(PDF)---025

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---002

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---018

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---011

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---020

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---003

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---009

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---001

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---012

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---015

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---027

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---026

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    Access 2000数据库系统设计(PDF)---029

    252.1 理解Access的应用设计方法 252.2 从模板文件创建Access应用 262.3 熟悉联系管理应用 292.3.1 数据库窗口中的表对象 292.3.2 切换面板窗体 322.3.3 Access窗体 332.3.4 Access报表 352.3.5 Access模块 362.4 ...

    2009达内SQL学习笔记

    3、对列起别名:有直接起别名,加AS起别名,用双引号起别名等三种方法 (单引号,引起字符串;双引号,引起别名。起别名有符号,或者区分大小写时,必须用双引号) 多表查询时,可给表起别名。(给列起别名,列&lt;空格...

    mysql数据库的基本操作语法

    主键约束相当于唯一约束+非空约束的组合,主键约束列不允许重复,也不允许出现空值;如果的多列组合的主键约束, 那么这些列都不允许为空值,并且组合的值不允许重复。 每个表最多只允许一个主键,建立主键约束可以...

    程序员的SQL金典6-8

     9.3.4 CowNewSQL的使用方法 第10章 高级话题  10.1 SQL注入漏洞攻防  10.1.1 SQL注入漏洞原理  10.1.2 过滤敏感字符  10.1.3 使用参数化SQL  10.2 SQL调优  10.2.1 SQL调优的基本原则  10.2.2 索引  ...

    程序员的SQL金典7-8

     9.3.4 CowNewSQL的使用方法 第10章 高级话题  10.1 SQL注入漏洞攻防  10.1.1 SQL注入漏洞原理  10.1.2 过滤敏感字符  10.1.3 使用参数化SQL  10.2 SQL调优  10.2.1 SQL调优的基本原则  10.2.2 索引  ...

Global site tag (gtag.js) - Google Analytics