找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2060|回复: 0
打印 上一主题 下一主题

mysql删除重复记录,保存Id最小的一条

[复制链接]
跳转到指定楼层
楼主
发表于 2016-8-23 20:58:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
方法1:0 H" p+ Z6 W' j: y$ c7 q
1、创建一个临时表,选取需要的数据。! V2 e2 `9 K( @
2、清空原表。
+ f5 ~! b7 @' P9 I3、临时表数据导入到原表。
+ l& w7 ?& i% J& ?4、删除临时表。5 Q* }  c/ W. x+ o& E
mysql> select * from student;3 [2 y2 _# p" Z! h
+----+------+, E" m4 D1 r# P9 \
| ID | NAME |# f2 f6 `7 U/ _* B
+----+------+
+ S* ~" T  W& c2 v| 11 | aa |
- l- @, o' j! J- b, Z1 c| 12 | aa |
0 o3 P# r: `4 v& G& L| 13 | bb |
; j- i# V- l. a! t| 14 | bb |
1 ^/ O! G8 R; _, {* T# x| 15 | bb |
( F4 X& i7 u. ]1 @( W| 16 | cc |
, ]( }/ V/ X# ?/ C* C, v1 k+----+------+' h( G1 }0 {6 _& |0 h$ E; J
6 rows in set
mysql> create temporary table temp as select min(id),name from student group by name;
' e# M4 _. m2 M* t0 e0 vQuery OK, 3 rows affected8 m9 g, k4 q& C
Records: 3 Duplicates: 0 Warnings: 0
mysql> truncate table student;* V) X/ Q: v- T  M- v
Query OK, 0 rows affected
mysql> insert into student select * from temp;
7 [% K. o. J! ~5 v6 TQuery OK, 3 rows affected
% l+ ], V0 ?& P# v) C8 r& ^+ nRecords: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;
9 {% u9 q! L" W' {+ v+----+------+/ _1 Q1 q. V. W2 T  K  b& O: z! Q( o
| ID | NAME |
' h; Z% y, b0 u( w: Y/ U# H+----+------+
; h! h6 @( T! Y* i- e| 11 | aa |
6 _# Y+ R! `% u$ N" }3 U' w| 13 | bb |( x% x. @: C# G% v3 ^0 l) k
| 16 | cc |' e9 P( j+ Z0 Q: g9 s
+----+------+& @8 M* A. ~0 c! f" J
3 rows in set
mysql> drop temporary table temp;4 L2 J* L: D$ K- f7 N
Query OK, 0 rows affected8 H3 P) e: c. O5 E1 v
这个方法,显然存在效率问题。

方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:
0 W" G1 g3 x. f$ B( rmysql> create temporary table temp as select min(id) as MINID from student group by name;
1 |! G, d! f& ?Query OK, 3 rows affected2 Q# i/ [# x- B* a. c; q) ?
Records: 3 Duplicates: 0 Warnings: 0
mysql> delete from student where id not in (select minid from temp);) J7 L  d6 Y8 Q3 Q6 J1 x/ E& H
Query OK, 3 rows affected
mysql> select * from student;# X6 o1 @1 Y" G7 p; z* S. I% b
+----+------+
6 ~: _% D1 f: Q( K; P$ V| ID | NAME |
) j8 b) k, m4 r  |+----+------+) f' M+ Y) A  U' e: y8 q2 j  W
| 11 | aa |; @7 J  `- }+ [. H' L
| 13 | bb |
/ a7 f% D; v: z3 F4 || 16 | cc |# u( B# @. }/ }0 h4 s6 g6 I
+----+------+5 d; a1 o- ^% u& m! A" U# t2 F, W
3 rows in set

方法3:直接在原表上操作,容易想到的sql语句如下:
mysql> delete from student where id not in (select min(id) from student group by name);
* \. y* z7 m  {% z执行报错:1093 - You can't specify target table 'student' for update in FROM clause% G* L% l7 F& V
原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。
8 p4 ^( @$ x$ X5 c! y1 g怎么规避这个问题?4 o( m6 B6 |. I1 g
再加一层封装,如下:
9 q: [1 f) p( B, A7 fmysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);+ I: l3 i1 H' i1 `2 D/ }/ e1 \" j8 k
Query OK, 3 rows affected
mysql> select * from student;8 @* ^9 q# f; H  f, U6 ?, ?$ i7 Z/ e; _
+----+------+4 P* W6 b# q/ [% \2 h# T" n4 F8 g
| ID | NAME |" T0 B0 d8 |5 l* _
+----+------+
# B- d) s* F1 J7 ^9 D0 e( C5 l| 11 | aa |- H; A) w# q- ^" Y9 {" ^: u
| 13 | bb |
( U. T+ {& j  P9 w| 16 | cc |/ f& S( i+ q% D) v6 P
+----+------+
# e+ y& H" |+ n# J+ M! B" w3 rows in set
( R4 C! o1 F! E. _
方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);
! S6 `8 ~9 O, x% d
" k. ]7 A1 H/ ^/ D4 i  o: Z/ m/ B- F5 X" l) ?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表