`

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

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. */
分享到:
评论

相关推荐

    hibernate的联合主键怎么设置

    在 Hibernate 中,联合主键(Composite Key)是指由两个或多个属性共同构成的主键,这种主键在数据库设计中常见于需要多个字段唯一标识一条记录的情况。在 Hibernate 中设置联合主键通常需要以下几个步骤: 1. **...

    eos开发中的联合主键使用

    联合主键是由两个或更多个字段组成的唯一标识符,用于确保数据库表中每一行记录的唯一性。在EOS这样的分布式账本系统中,数据的完整性与唯一性尤为重要,因此理解并正确使用联合主键是开发者必须掌握的技能。 首先...

    删除表中重复记录

    在SQL中,删除表中的重复记录是...以上就是SQL中删除重复记录的方法,无论是否有主键,都可以通过不同的策略来有效地处理重复数据。在实际操作中,务必谨慎,确保在执行删除操作前备份数据,以免造成不可逆的数据丢失。

    oracle删除主键查看主键约束及创建联合主键

    本篇文章将详细讲解如何在Oracle中删除主键、查看主键约束,以及创建联合主键。 1. 删除主键 在Oracle中,删除主键约束有几种方法。首先,你可以尝试使用`ALTER TABLE`语句删除主键,语法如下: ```sql ALTER ...

    python django model联合主键的例子

    在某些情况下,我们可能需要为模型设置联合主键(Composite Primary Key),即由两个或多个字段共同构成主键,以确保数据的唯一性。本篇文章将深入探讨如何在Django中创建联合主键,并通过一个具体的例子来说明。 ...

    初探SQL语句复合主键与联合主键

    SQL中的主键可以是单一字段,也可以由两个或多个字段组成的复合主键,或者多个字段组成的联合主键。下面我们将深入探讨这两种主键类型。 1. **复合主键**: 复合主键(Composite Key)是由表中两个或多个字段共同...

    查询重复数据sql语句

    - 当只需要知道是否存在重复数据而不需要具体的重复记录时,可以使用`COUNT(DISTINCT column_name)`。 - 示例:`SELECT COUNT(DISTINCT id) FROM a;` ### 总结 本文详细介绍了如何使用SQL查询表中的重复数据,...

    精髓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 --不等于 ...

    深入探讨SQL_Server_表的主键问题

    如果业务需求进一步细化,可能导致联合主键的出现,如销售单号与商品编码的组合。然而,这样的设计会带来一些问题: 1. 数据冗余:随着主从关系的加深,为了保持关联,从表需要存储大量重复数据,这可能导致数据...

    MySQL 消除重复行的一些方法

    首先创建一个新的临时表,结构与原表相同,并插入原表中不重复的记录。然后删除原表,最后将临时表改名为原表。例如,创建一个名为`test_1`的表,插入重复数据,然后创建一个临时表`tmp`,将`test_1`中的不重复数据...

    分享SQL Server删除重复行的6个方法

    4. **联合主键**:如果多个字段组合起来形成一个唯一的标识,可以使用这些字段的组合来删除重复行。例如,`col1`、`col2`、`col3`的组合。代码如下: ```sql DELETE FROM table WHERE col1 + ',' + col2 + ',' + ...

    权限控制与安全管理设计文档

    联合主键:AIRLINE + CHANNEL + SERVICE_NAME + VERSION ##### 4.3 Service信息表(API_SERVICE_INFO) | 字段 | 类型 | 描述 | |---------------|----------|--------------------------------------------| | ...

    专题23:Mysql 面试题(卷王专供+ 史上最全 + 2023面试必备)-V106-from-尼恩Java面试宝典.pdf

    - 辅助索引: 非主键索引,用于辅助快速定位数据行。 ### 2. 索引的工作原理 - **B+树**: - 所有叶子节点包含所有键值以及指向实际数据记录的指针。 - 内部节点仅包含键值和子节点指针。 - 这种结构使得B+树非常...

    程序员的SQL金典(完整版).pdf

    - 使用 `DISTINCT` 关键字去除重复记录。 **4.6 计算字段** - **常量字段** - 直接在 `SELECT` 语句中计算常量值。 - **字段间的计算** - 对字段进行加减乘除等运算。 - **数据处理函数** - 使用内置函数如 ...

    学生选课数据库SQL语句练习题(sql 语句)

    - `Degree`: 成绩,`Sno`和`Cno`组合为联合主键。 - **表(四)Teacher(教师表)** - `Tno`: 教师编号,为主键。 - `Tname`: 教师姓名。 - `Tsex`: 性别。 - `Tbirthday`: 出生年月。 - `Prof`: 职称。 - `...

    SQL语句练习--数据库

    - **知识点解析:** 使用`DISTINCT`关键字去除重复记录。 10. **查询选修C01课程的学生学号和成绩,并要求对查询结果按成绩的降序排列,如果成绩相同则按学号的升序排列:** - **SQL语句:** ```sql SELECT Sno...

Global site tag (gtag.js) - Google Analytics