方法1:3 O' ^; V' m. Q: ?6 |; W0 A$ }( k6 u
1、创建一个临时表,选取需要的数据。
+ j; x* h" M2 M1 h. w$ }2、清空原表。
# G' P' w7 \' d5 A) Y7 s3、临时表数据导入到原表。
% I1 \1 g/ H$ S4、删除临时表。
3 n' y6 \# V% f* q7 Umysql> select * from student;8 Y5 i- u& T5 I$ J
+----+------+! o7 E, s0 K; b2 a* h: p' |
| ID | NAME |
6 V2 {8 M* W2 \, W& E, ^4 t+----+------+1 ]' ]0 f7 R j8 w2 V
| 11 | aa | x" {) U4 b* \, r/ r/ L, i8 o: y
| 12 | aa |6 n4 a" o8 ^; S# @) {- r' J
| 13 | bb |9 j+ b- \/ w% Q" t$ z% p
| 14 | bb |! Q8 r' Z1 `2 T) J7 b9 R
| 15 | bb |9 | L$ w9 t! u5 {
| 16 | cc |/ o* ~! T: `+ ?6 K- ~
+----+------+
- y( V$ L( s9 t* z# S6 rows in set mysql> create temporary table temp as select min(id),name from student group by name;
6 n6 b3 Q, ~2 b- lQuery OK, 3 rows affected3 T; J" `; g9 F5 O3 ^. W# L
Records: 3 Duplicates: 0 Warnings: 0 mysql> truncate table student;
+ x. G8 ^* A* L' sQuery OK, 0 rows affected mysql> insert into student select * from temp;
9 j; P0 N, b0 y( r, yQuery OK, 3 rows affected4 Q9 @% J: C& Q" Q5 M, t! K6 _
Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from student;
& n# B& I6 m! m# l1 m2 Z8 U+----+------+0 X; Z1 M# C8 z4 x9 N
| ID | NAME |
: F9 M" {2 Q5 a% O" i5 j9 y+----+------+
0 M/ x6 s0 Y* D, g% y* m R' L| 11 | aa |
0 m/ y. }) m/ @5 |& F. N1 U u| 13 | bb |: I' ~$ H/ o. m; S: ~! d: Y
| 16 | cc |
' w* F9 m& p0 `4 F: f, U+----+------+$ |9 m( ?# |, v. b) n2 ^* Z! S
3 rows in set mysql> drop temporary table temp;4 H% u3 p+ e2 \ f5 ~: J5 Y
Query OK, 0 rows affected) z9 i9 `# a! F. `, d2 b: L5 H
这个方法,显然存在效率问题。
方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:" e) y0 W- f4 C* R7 J3 j7 w
mysql> create temporary table temp as select min(id) as MINID from student group by name;* e$ n* }: z) q. B: R
Query OK, 3 rows affected
, ~0 |4 x, x9 o3 W: ^Records: 3 Duplicates: 0 Warnings: 0 mysql> delete from student where id not in (select minid from temp);
3 {6 L* X- V5 p \2 O3 ? R; ]Query OK, 3 rows affected mysql> select * from student;
. O q1 r2 Z. j+ B! I0 h5 O+----+------+5 o% L7 I/ X$ f* ?& G+ P0 B, i: D
| ID | NAME |7 B8 N; m7 M4 e2 \" C$ Q$ l2 p
+----+------+5 [1 I3 g4 m8 i& X. U+ e9 G. t
| 11 | aa |' J8 ?& n! Y& g, F, K/ L
| 13 | bb |0 K' ^) O; T4 {
| 16 | cc |: u; ~$ l3 C G, w! _$ B
+----+------+
) M3 \! E7 O* q5 K3 rows in set
方法3:直接在原表上操作,容易想到的sql语句如下: mysql> delete from student where id not in (select min(id) from student group by name);
$ J3 ~2 l" g1 {' S/ N) D( m执行报错:1093 - You can't specify target table 'student' for update in FROM clause
. q s2 r' g; N2 ?9 m. U) X2 T原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。
) H% I/ g: o6 p3 _ m# U( [怎么规避这个问题?
: l i3 y9 a) B) J% P( B# x再加一层封装,如下:
( N7 }2 q$ Z5 u/ @mysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);
' R6 V) d T! W2 I& d" ?! IQuery OK, 3 rows affected mysql> select * from student;
2 e) Y. j9 d/ H6 `4 u5 a+----+------+1 ~ q- A( _/ Z
| ID | NAME |
/ j d/ r! P; _+----+------+
# y3 T4 w& k0 t4 d. ~ c8 @; v3 w6 s @| 11 | aa |( p" U+ {- @) T; Q
| 13 | bb | T$ A. L( h& n) j
| 16 | cc |! W, v8 f4 i# ?3 d
+----+------+, e$ w' p1 U: @0 p6 F
3 rows in set
. K+ Y1 |: B/ L# a3 w方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);
* R, v9 E. X8 [2 i7 J: a# G9 j" ^$ ]2 A$ q
# t$ F, h2 I3 a) X x0 P( S( z+ d6 x
|