找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 1867|回复: 0
打印 上一主题 下一主题

mysql删除重复记录,保存Id最小的一条

[复制链接]
跳转到指定楼层
楼主
发表于 2016-8-23 20:58:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
方法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
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表