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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2016-8-23 20:58:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
方法1:# F, H( ^# t" ^! d% X/ K
1、创建一个临时表,选取需要的数据。
  O$ `8 w: p; W/ v$ A* F! l2、清空原表。5 l1 \% p$ _, A% l8 _
3、临时表数据导入到原表。
8 _) }9 g2 R% @( B7 a4、删除临时表。
" j- B- d/ B/ lmysql> select * from student;
( Z  U+ e6 j- F. B# C9 o% P$ n# ]+----+------+
- m7 G. R" u0 U/ b, Y# g/ n. X| ID | NAME |  \3 R  k" z" x2 T' F7 T8 t" Q9 U
+----+------+
  k2 L0 W! ~1 R! `$ v; T/ g| 11 | aa |
8 q  c0 _: M/ p+ c$ R: S| 12 | aa |' W& Q% A' t% }, f' L: B, y5 K8 A
| 13 | bb |
8 a; _( r& j) l# f1 J2 r8 w| 14 | bb |8 K% G1 q7 i' q, ?& D& V
| 15 | bb |
3 o' Q. P" c& |' f5 }' v| 16 | cc |
1 g! g* K4 [! p3 |% ^9 p) ~2 v+----+------+
; I5 R% _! |' S7 y6 rows in set
mysql> create temporary table temp as select min(id),name from student group by name;9 N( G  f3 y4 c1 @. M
Query OK, 3 rows affected
) E" F1 M0 }+ GRecords: 3 Duplicates: 0 Warnings: 0
mysql> truncate table student;
) ^  H5 Q0 e3 T( AQuery OK, 0 rows affected
mysql> insert into student select * from temp;
. ?% v' j% p: C; ~) aQuery OK, 3 rows affected
/ u' x1 b  ?* r7 J' e1 ]! GRecords: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;
2 K* {4 S7 U2 G+ K  R2 y# S+----+------+) K' L  x1 F$ }4 f% N# m9 B
| ID | NAME |1 _! r$ }& c6 [, Z! h8 r: A
+----+------+5 Y/ `( b- `# c0 r; O) R
| 11 | aa |, t; y4 d: ?' ~* W- Y: d
| 13 | bb |) _" x3 G% v* v- B  A
| 16 | cc |1 v/ I9 D' U3 v7 [$ M
+----+------+
7 E' v2 f+ P" M" u- u& r3 rows in set
mysql> drop temporary table temp;
! u  m2 g# w3 C. R" ]Query OK, 0 rows affected
: y7 c/ `4 c" }( n这个方法,显然存在效率问题。

方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:
7 |- t" g5 K% e/ n* r8 w, Nmysql> create temporary table temp as select min(id) as MINID from student group by name;) _4 {' y7 p( f  b# Y
Query OK, 3 rows affected3 r3 w4 _# ^: K3 M9 ^
Records: 3 Duplicates: 0 Warnings: 0
mysql> delete from student where id not in (select minid from temp);' v/ ]. x* D8 I, a/ L' Y6 f" g
Query OK, 3 rows affected
mysql> select * from student;( p6 _  e& X; Y0 X; H
+----+------+
9 Y) m0 J8 D. r1 {| ID | NAME |
; x! d& m& o3 s( k: Z  W; e/ @$ ?+----+------+, a  F5 `$ p3 T& N6 Z' ^3 S# a
| 11 | aa |7 P, m4 {# ~+ |+ b5 x$ y* x: x
| 13 | bb |
$ F7 T9 n0 q+ v) k9 w| 16 | cc |* X( A. `- k# H
+----+------+$ }" P1 C; F) ^6 G6 Q# U, y: x
3 rows in set

方法3:直接在原表上操作,容易想到的sql语句如下:
mysql> delete from student where id not in (select min(id) from student group by name);
1 ^8 J/ J( e4 A' p- ^执行报错:1093 - You can't specify target table 'student' for update in FROM clause: n2 G$ m7 ?, v3 @/ P
原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。3 Q) T- e3 P3 i7 M: N
怎么规避这个问题?. H5 L0 u3 R, r! w  O( Z
再加一层封装,如下:
, w' d) @+ `9 F# M. o) dmysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);% W: F- k9 O' E. \. M' V, p2 v; m
Query OK, 3 rows affected
mysql> select * from student;
3 w" E. z# ]) [& R: p3 b8 r+----+------+! c& R$ d/ p  b3 _5 G: e+ I3 B
| ID | NAME |' I3 u% x: K& t
+----+------+3 Y; X  F+ K9 E8 }& z# v8 ?7 d$ n
| 11 | aa |. J& h  [: }$ I# @0 l  M, g
| 13 | bb |! X: d) F( L( |- h7 H
| 16 | cc |
3 r7 ?7 b/ k2 h; [$ k- F* L8 ]- E+----+------++ M' I" n0 Y9 l: C' v
3 rows in set
$ Q8 ?/ k& m( {7 Z
方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);
/ f6 y$ |2 v0 Z
6 a3 ?$ K( ?4 K$ l# i- w+ m9 b4 ?' f% D6 A
回复

使用道具 举报

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

本版积分规则

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