方法1:
; L& f) z( M1 d. d7 p' ^0 v: s2 p1、创建一个临时表,选取需要的数据。; E5 m/ T8 r9 O; T$ E9 r
2、清空原表。1 X- T; P$ r/ h/ N: o/ l
3、临时表数据导入到原表。6 R8 V& C$ O* V! z$ j
4、删除临时表。, `6 ^6 y7 C" I, t. G0 j6 J: b+ O
mysql> select * from student;
# K/ r! c) ~* r1 O3 Y& P! \* t+----+------+; U4 V3 {5 g' K/ y9 }1 F0 T, I- `4 Q3 y
| ID | NAME |+ @' u. j; i2 w; O j
+----+------+1 C# w+ G! b8 r) X6 Z, w3 c. j8 b
| 11 | aa |
& i5 d; t& r( O- n7 R6 S| 12 | aa |
5 t2 `$ _2 |, l! C' X| 13 | bb |
4 k& C Q% @$ B, k0 P! u| 14 | bb |$ B. s# W6 Z3 l8 m: X
| 15 | bb |
: y2 U* }5 V `, B& R| 16 | cc |. [+ F1 Y" `, f( C3 H
+----+------+0 d% u+ c: F Y X
6 rows in set mysql> create temporary table temp as select min(id),name from student group by name;
/ c' w; D) |" E; n6 l1 Y% f4 aQuery OK, 3 rows affected
3 U$ d0 E9 N j* V4 K- y5 K, tRecords: 3 Duplicates: 0 Warnings: 0 mysql> truncate table student;
% W3 K1 v0 J4 N6 T8 \2 TQuery OK, 0 rows affected mysql> insert into student select * from temp;" c* C% v& G: X# X
Query OK, 3 rows affected5 i% l% E2 t- ^: D/ p" K7 T
Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from student;! _& M E* \ J/ M
+----+------+7 C7 X5 Q/ U" ]. P! {1 F+ `( F
| ID | NAME |
+ u8 I' d" V& r( N4 w! x) b+----+------+, Y8 y& b$ F/ f* Y% {! Y
| 11 | aa |' J" N! u4 o- Z/ Z
| 13 | bb |
/ l) k) [' Y8 i* X" `3 @! }| 16 | cc |5 @0 i6 \/ i" h* u& U* o' D
+----+------+
8 |: c1 T, f* f v; k3 rows in set mysql> drop temporary table temp;# T% V1 Z: C4 r- z: F9 |
Query OK, 0 rows affected
5 ]6 M+ n+ w7 l# |5 ^8 Q" S/ G: b9 L这个方法,显然存在效率问题。
方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:
6 O0 X2 ~9 {$ C# o- p" lmysql> create temporary table temp as select min(id) as MINID from student group by name;
( u& D# Q1 x; X* q4 ?Query OK, 3 rows affected
- [( N' |- i ]0 e7 e WRecords: 3 Duplicates: 0 Warnings: 0 mysql> delete from student where id not in (select minid from temp);
: O" t7 T5 I. D$ R$ qQuery OK, 3 rows affected mysql> select * from student;
- C6 M' N2 V5 F2 C$ V9 d0 N+----+------+9 \4 ^5 B7 F- [' T: {0 b+ U
| ID | NAME |
6 p8 N( U9 x: C- ], i; f+----+------+6 {* |/ A7 N! e4 A Q, F; U
| 11 | aa |. T7 S) H7 i. Z$ S) `. v% v6 S% `
| 13 | bb |
, u; X; k$ j! k' \+ F4 e| 16 | cc |
( m) h: [. ?7 A* }$ W, w+----+------+
5 Z, e5 y* r0 e* W/ x" a3 rows in set
方法3:直接在原表上操作,容易想到的sql语句如下: mysql> delete from student where id not in (select min(id) from student group by name);
" ?' E# j5 v0 J* b( F执行报错:1093 - You can't specify target table 'student' for update in FROM clause B& s$ \7 q/ b
原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。
4 G* v) Q& ?, w; }怎么规避这个问题?
0 `; {. l5 G# z9 P; a, ?4 v再加一层封装,如下:4 T+ {2 i( V' p; T
mysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);5 q1 H& o- t) C$ y$ d9 V/ j0 n
Query OK, 3 rows affected mysql> select * from student;
1 F) C$ d( A2 X& {2 r6 Y+----+------+
8 O7 p' j, h' G' h9 {) V2 d. o; b- {| ID | NAME |/ c, {, C$ L. }$ K) z% ^) `' S
+----+------+
1 D1 y8 ]0 c& B+ m/ r9 D0 m| 11 | aa |) g& y1 C& G! y- h3 Z* f) ?2 e5 L1 _
| 13 | bb |5 K* a, J3 X7 ^/ g& `6 e$ {" {; o: A' P
| 16 | cc |' `) i' }$ }" k( P" v; ^/ h7 S3 @; {
+----+------+8 a$ _7 k9 `, Q2 X* f/ u8 q
3 rows in set
: \7 \5 d% n+ F- B0 n+ z7 M ]2 U方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);
, S8 M% V: @( i6 l
) `! K" j( z! l3 A# ^5 K/ z- M% S- j1 N2 Y3 L* N; J5 I9 O
|