方法1:" ]% W$ i* H4 k: F% P; p+ ]
1、创建一个临时表,选取需要的数据。9 }# z9 ]1 N6 G3 _! q$ J
2、清空原表。2 f3 r$ p: Z! _7 l( _1 U; M9 i. E
3、临时表数据导入到原表。- l, h0 z( z) k" b( y ]; G
4、删除临时表。& L, A, e" s* B7 G' [. a! W
mysql> select * from student;
* _" v/ D5 Q- q+----+------+
' P2 _7 {- u0 G% E* ^| ID | NAME |
4 d7 c4 W8 _& B5 b. X+----+------+
$ `# N8 s; {8 b: D0 s! f| 11 | aa |! S: x( B+ u$ J5 X6 R+ V9 f2 B
| 12 | aa |% `) w& X; c" I; U$ }
| 13 | bb |
7 t" n' c$ x* l| 14 | bb |
9 T- n) K' f. @: C* ?* P6 Q| 15 | bb |/ E( T y) Y/ X. O: A
| 16 | cc |
$ X- ^) r2 ~$ E2 E. w& K/ m1 Y+----+------+
% Q: u; \ ~% l8 l6 rows in set mysql> create temporary table temp as select min(id),name from student group by name;
3 [) T8 Q* w. O( x2 c, bQuery OK, 3 rows affected8 W5 m3 ]6 l3 R- M
Records: 3 Duplicates: 0 Warnings: 0 mysql> truncate table student;; y; d, V4 B8 K( ^6 B3 h
Query OK, 0 rows affected mysql> insert into student select * from temp;' z& @! f+ |& O" w- M
Query OK, 3 rows affected
2 _4 T( _ \' l# V, d P9 dRecords: 3 Duplicates: 0 Warnings: 0 mysql> select * from student; B# z6 E* c6 l
+----+------+
+ Q% b; H+ T! ]0 K9 @6 {9 l| ID | NAME |/ Z6 C* ~& E/ U! x
+----+------+* X8 @$ L+ Y9 E. y; W4 z
| 11 | aa |! A2 S& i9 ]5 D* A# l' J" u, ^0 [1 _
| 13 | bb | a) V0 ]; }" r1 n1 g" _
| 16 | cc |
1 C, S7 H3 i. h4 m3 H% t+----+------+
2 p9 s* S& o& u! h- V# t3 rows in set mysql> drop temporary table temp;, T2 d! N% b) W$ S! N
Query OK, 0 rows affected
$ B2 r" y+ T/ B, |) H这个方法,显然存在效率问题。
方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:
" \. `4 V/ K# e, L& Omysql> create temporary table temp as select min(id) as MINID from student group by name;6 N' w- }8 ]. p) H
Query OK, 3 rows affected
4 }! E1 F$ _/ ^0 m" ERecords: 3 Duplicates: 0 Warnings: 0 mysql> delete from student where id not in (select minid from temp);
; |8 L. P) i3 s `, Y, P$ zQuery OK, 3 rows affected mysql> select * from student;& @: a# O: f1 P
+----+------+0 m% ^' R8 W4 J; t7 Q
| ID | NAME |2 M$ i. J4 v% [' E5 q. Q
+----+------+
- A! p7 p5 t1 || 11 | aa |
# ` l$ S6 E& F' U, o) {| 13 | bb |; E" a+ B7 {7 \
| 16 | cc |$ k' @( S }: |4 Q# T. P* U+ m
+----+------+
" R5 E9 n+ w# Q3 rows in set
方法3:直接在原表上操作,容易想到的sql语句如下: mysql> delete from student where id not in (select min(id) from student group by name);3 R* A8 p: b- ?1 s9 _4 G) C
执行报错:1093 - You can't specify target table 'student' for update in FROM clause
5 b' l3 F6 Q+ |5 m: j; } e原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。
5 j0 V: o) z! C怎么规避这个问题?. g$ K+ t- m# F7 c1 e5 w& K
再加一层封装,如下:
0 x/ ?. H- {. H6 R1 E9 z- A7 |" qmysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);
) h: a# }! m! S* ]1 h$ R* @* OQuery OK, 3 rows affected mysql> select * from student;
9 A5 X: g- a) X) a: v$ Z+----+------+7 U% o: m$ ]- a2 x
| ID | NAME |* }3 A# x" ~6 `% I, F+ }
+----+------+
& O/ l- H+ }4 \8 o( || 11 | aa |# v+ i( H n3 D8 h0 H
| 13 | bb |, n2 {, i) W/ M
| 16 | cc |; A: P9 g# r& r1 o5 [5 n- K
+----+------+
) P0 j. ^8 e, W0 f8 T" l3 rows in set - Z% a' n2 x4 l/ V P
方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);$ E2 k$ d0 Q5 j
t$ S8 m2 _- [; A7 O
|* \) |+ I# F" `" ^6 E# x2 Y |