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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2016-8-23 20:58:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
方法1:1 r5 \4 U% Z; ?3 O. |- ?: Y
1、创建一个临时表,选取需要的数据。
/ L0 n: e/ l- B  t3 o% C7 B2、清空原表。( L0 u4 U9 W; X0 J3 w
3、临时表数据导入到原表。
5 n, a) H; T" k9 Q( @4、删除临时表。+ _3 a4 D3 G4 [0 o8 N, @+ F9 q
mysql> select * from student;
9 e! q% h3 B6 v5 L  E- \" O. W# j+----+------+
/ n; V  _3 I7 g0 M2 h6 j$ A3 b2 j1 L  `| ID | NAME |2 i& h$ k9 r1 W- m* b
+----+------+
/ W' r2 V: C6 Z9 N$ @8 R+ M| 11 | aa |% _- [  b7 E3 n0 @" Q
| 12 | aa |
+ V$ m3 G6 ]5 g' L: I: W6 J; M( X| 13 | bb |: C5 G5 Z- Z4 ~8 B& N7 |
| 14 | bb |; _# Q4 ]& H/ g
| 15 | bb |( v4 P+ _1 V! a9 z
| 16 | cc |
/ ]8 y$ X0 O) [. m* g2 B+----+------+0 M" I; z+ `/ D
6 rows in set
mysql> create temporary table temp as select min(id),name from student group by name;
5 V# c; I( x5 N# g4 N6 r/ BQuery OK, 3 rows affected
/ A1 ~5 M* w% w: f- h1 R. f- aRecords: 3 Duplicates: 0 Warnings: 0
mysql> truncate table student;
9 L( x9 [, {9 X$ \5 {! qQuery OK, 0 rows affected
mysql> insert into student select * from temp;* j1 u8 W4 c- x& M4 l
Query OK, 3 rows affected
. Y/ O( L* a. Y& h0 {0 U( P2 T& SRecords: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;1 U6 t, z. v7 D. c  H- c( N8 ~
+----+------+
/ V5 {+ ~" x0 \: Q! h8 d% G| ID | NAME |
; G6 g; G5 |. _1 A* ?5 Q+----+------+7 A8 t( D5 Z; s# V) D/ J, R
| 11 | aa |& J  Y: P; q: o/ {& V- m: ?
| 13 | bb |
* p6 Z7 Q4 E6 s* m( k| 16 | cc |# l6 V1 T4 a! N1 f* |& Z
+----+------+! Y7 S' Q3 |; R/ P( q2 Y. A) @  A
3 rows in set
mysql> drop temporary table temp;! \, v& l! @* D: _# j( b  p- T
Query OK, 0 rows affected% _" z# U& T/ U
这个方法,显然存在效率问题。

方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:" G" Y2 i) O1 ], p; @$ J
mysql> create temporary table temp as select min(id) as MINID from student group by name;8 z' u# F2 I/ G5 }
Query OK, 3 rows affected5 g8 W; y* j# u  J  q( o
Records: 3 Duplicates: 0 Warnings: 0
mysql> delete from student where id not in (select minid from temp);
# G7 V6 r2 O& d/ O8 Z' n" v; IQuery OK, 3 rows affected
mysql> select * from student;8 @0 n3 \2 D! w6 f
+----+------+, u& {0 y7 @; t0 u3 k
| ID | NAME |
# u; H, T! ~; `8 P- f, d' ^, ^+----+------+. x0 [8 o3 T. l# F7 l  z- F6 Q6 G
| 11 | aa |
8 W% f/ H/ F$ V& U( j8 ~! o| 13 | bb |7 p( W* G3 k" Q( `& ?: k! [
| 16 | cc |
/ \9 Q" k& y1 F  E' s0 D+----+------+
1 X, `- ?0 k; c( f: `  [% W" [3 rows in set

方法3:直接在原表上操作,容易想到的sql语句如下:
mysql> delete from student where id not in (select min(id) from student group by name);2 G& Y) e- r  R  j  i
执行报错:1093 - You can't specify target table 'student' for update in FROM clause. b8 p) x; |6 s  C0 ~6 R
原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。/ M1 Y$ Y! s5 G' K8 b9 r7 N" K
怎么规避这个问题?/ a0 u: i* T+ ]
再加一层封装,如下:
' n$ y+ @4 O2 L* Z/ N( }  `! U7 Cmysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);1 T* P' I4 F0 P
Query OK, 3 rows affected
mysql> select * from student;0 Y/ c6 i/ T' Z* N" r% W; ?
+----+------+
3 s4 ]6 N3 n* a4 F9 V| ID | NAME |1 x! A% k. t# j/ ]
+----+------+
+ w2 i9 c1 S9 N1 ^- J2 t7 }| 11 | aa |& t  Y7 Q" W. B  Z! z5 L. a
| 13 | bb |* D  O1 X% q& G
| 16 | cc |
! q: ]! v% [& R0 W2 f9 O- F+----+------++ g8 s5 V- ?8 O0 ~# g& m
3 rows in set
3 W* u4 S; F  |6 N# @, B& p
方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);
5 Q6 m* U- `' \, R* h1 M% o: n) S5 v  H' ~7 `( W
- Q, w/ L% X" Z; [, a5 f& Y
回复

使用道具 举报

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

本版积分规则

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