方法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
|