|
方法1:& {1 D# V: K( r& P
1、创建一个临时表,选取需要的数据。
) j: D, S: } X3 x- a# r$ H2 c* n$ Z2、清空原表。7 | T: s7 Y+ b" }; d# c Y4 i c
3、临时表数据导入到原表。* z: h& h" B1 b9 t
4、删除临时表。
8 Y' F% F) I+ i( ~mysql> select * from student;
R' ^ N3 ^0 ^+----+------+
: D; N0 }- t0 j7 c/ q. K| ID | NAME |6 K8 q3 f, {% E7 D- ~
+----+------+
: K0 }, ~: p3 F: \+ k" v| 11 | aa |0 f3 P" S* h1 Q4 d+ g( P+ {
| 12 | aa |
/ s A$ K0 V% c4 T& ?: s| 13 | bb |+ c; e" }# S* | q, h6 W" C
| 14 | bb |8 C7 Z% o, e- o e1 `8 k- {' E
| 15 | bb |
% b, |% g1 M |1 J: C7 ~% R" i; M| 16 | cc |
7 ^3 J5 I6 M9 B2 J; o7 P+----+------+4 W+ r& F# I" g
6 rows in set mysql> create temporary table temp as select min(id),name from student group by name;$ v) r1 K% q5 o9 Q* J5 n
Query OK, 3 rows affected9 ~7 L5 s& j1 J6 y" g, @
Records: 3 Duplicates: 0 Warnings: 0 mysql> truncate table student;
; j$ h% V' j( f# wQuery OK, 0 rows affected mysql> insert into student select * from temp;( |( d( F/ k: R, ^
Query OK, 3 rows affected
$ V1 N6 e3 k8 u8 ^8 u9 a' w- WRecords: 3 Duplicates: 0 Warnings: 0 mysql> select * from student;% Q U4 ]0 C5 {: L0 z4 l
+----+------+ j/ V, A+ b: [9 G5 q x# H
| ID | NAME |+ C& z4 U5 _7 w: U9 C: S5 o9 o
+----+------+
0 ~: L9 |3 R. S8 L S0 i: v| 11 | aa |
/ w: _) Y% o9 q6 ]8 f& |/ G7 {, v| 13 | bb |
3 h( f5 I9 N8 X( r' L| 16 | cc |
; X) J3 \2 j% @! n0 ?8 n* B+----+------+
# d! L+ e# q: u* Y2 [+ E3 rows in set mysql> drop temporary table temp;
9 f. Y- O0 _; TQuery OK, 0 rows affected+ c, h. M8 U" j' a" R
这个方法,显然存在效率问题。
方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:9 V/ _- V/ v. q# d( `8 h1 U. X
mysql> create temporary table temp as select min(id) as MINID from student group by name;
, f1 m) n8 @0 L- f! O% Q9 p6 xQuery OK, 3 rows affected
$ r( `) A; R! ^- x' ^1 uRecords: 3 Duplicates: 0 Warnings: 0 mysql> delete from student where id not in (select minid from temp);
7 J3 c- m: d! X8 ]/ B( S. J: d: d0 kQuery OK, 3 rows affected mysql> select * from student;
# U2 D" Z4 K" ?. V$ r2 j" e6 P+----+------+) H: s% L8 V" G0 ^ w, w
| ID | NAME |0 \) e% A) ^( a/ o0 E, v7 ?; G
+----+------+0 Y/ I0 j" H G. ^
| 11 | aa |
( |& W, d) A0 L: b& ^| 13 | bb |
7 o3 p& E5 [: Y J# k| 16 | cc |* y8 L. \ E4 B/ z% ^
+----+------+1 l0 V- X& O3 f3 Z) X( Q
3 rows in set
方法3:直接在原表上操作,容易想到的sql语句如下: mysql> delete from student where id not in (select min(id) from student group by name);# |; H& w, q& o, ~8 P! H1 `$ l; ~2 r5 J
执行报错:1093 - You can't specify target table 'student' for update in FROM clause/ e |) K/ ~6 y( C9 J
原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。8 j. I( ^ ~& E. ]
怎么规避这个问题?
: D* g/ b1 I$ n9 i$ x! ~6 V' l再加一层封装,如下:% h6 \+ O- l( r- r9 k$ q
mysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);2 f: ]. d5 E* S Y9 U! o
Query OK, 3 rows affected mysql> select * from student;
6 K" R1 Z0 w- E# F4 q+ }+----+------+* c K4 p& k4 i
| ID | NAME |* f4 {9 d8 g: t, v
+----+------+9 G7 k0 J, q$ P/ E
| 11 | aa |
7 G1 x8 {% I ]: |% e2 r| 13 | bb |, E( I' b4 x3 V& t* A+ |
| 16 | cc |$ Z3 C* z# K M* y8 Z& k$ ~
+----+------+
# ]2 w+ X, u, B E7 n/ [3 rows in set |4 `' z: A- l W7 s! q( b
方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);2 R: F. `6 D* Z$ x
/ X) [& y: s- D9 s+ o0 Z- ~( a3 b/ v; t' P Y: d, e
|