找回密码
 立即注册
查看: 2835|回复: 0
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
楼主
发表于 2016-8-23 20:58:17 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
方法1:
) |: {) t5 t$ x; P9 y  q1、创建一个临时表,选取需要的数据。
& f; |. C/ {. Q9 c) V: t8 ?# a& j2、清空原表。
( b. R% ~! K8 n) f* R: P3、临时表数据导入到原表。5 G" v5 E5 A8 }3 e, J$ Z" z9 J
4、删除临时表。
1 N, G7 ?% B: S7 K" u$ I& S3 |mysql> select * from student;
6 O9 g9 B% V& j) p9 N+----+------+
, A* ], F8 |9 Y| ID | NAME |2 ]4 `. {7 H8 u* }! n8 l
+----+------+: _' u9 _# }  i: T, R  y
| 11 | aa |
8 }! f$ a  j6 E% F- L' e4 R1 R| 12 | aa |
' w% G8 }  B# E1 i. V' u" O/ T| 13 | bb |
3 u/ Y& o$ s* Z8 u4 f  u: v7 q| 14 | bb |/ _/ G$ t9 m+ }7 W" y
| 15 | bb |
/ E, n( ?  x) T" Y" x7 ?| 16 | cc |
7 S( I& Y0 |( @2 z6 n, y$ D" i+----+------+- |4 P% G- A. F* F6 Z5 k
6 rows in set
mysql> create temporary table temp as select min(id),name from student group by name;
5 c. A, G/ H4 v/ _Query OK, 3 rows affected7 s' F- w' w  ^' W, M  d
Records: 3 Duplicates: 0 Warnings: 0
mysql> truncate table student;. ~4 ~, d1 E, x8 M
Query OK, 0 rows affected
mysql> insert into student select * from temp;! r2 K  ?# z) I7 m! o) J5 B
Query OK, 3 rows affected! y  `- s( m! N8 l+ L
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;5 ]. @( K/ B- |( R! X) U4 e
+----+------++ B7 Y, i& n, K1 e+ ~
| ID | NAME |/ _! O( O  L6 s
+----+------+
' M( B0 N7 q) ?5 ~# n# |" ^1 n3 P, H+ A, T| 11 | aa |6 o8 [  r$ V8 q- \- P, }' ~
| 13 | bb |
) i1 Y* y7 h. i% n/ h| 16 | cc |
6 u/ ~2 ?5 c& A. D' r" W5 z" c+----+------+0 M% [" y' o3 ?- M
3 rows in set
mysql> drop temporary table temp;5 U! S! m5 G9 r' b
Query OK, 0 rows affected& r, ^& ~4 N1 ?; J6 }$ B9 x
这个方法,显然存在效率问题。

方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:
' _; Q, r6 z# |0 Jmysql> create temporary table temp as select min(id) as MINID from student group by name;
- Q$ Y  N. ]$ T- n' `Query OK, 3 rows affected. q  u- M* I2 f* k
Records: 3 Duplicates: 0 Warnings: 0
mysql> delete from student where id not in (select minid from temp);
4 T! H8 \( q1 m. F% [' rQuery OK, 3 rows affected
mysql> select * from student;4 ~+ Y- O& @8 Y8 p4 h+ R: s7 e
+----+------+
$ V3 r& S& z0 Z( r7 ], s& }& [| ID | NAME |
8 [) i! y) w7 S; a/ q6 m$ i+----+------+8 K; L. N$ m) s% E# ?' b/ E+ T
| 11 | aa |
# S, J$ b* h; Z  X| 13 | bb |6 s! A/ i2 X' B2 }( G
| 16 | cc |
+ i3 R/ Q3 r1 X; B* I0 B9 E7 [+ s) [+----+------+/ w4 m+ U+ n) k0 L/ W" R5 y
3 rows in set

方法3:直接在原表上操作,容易想到的sql语句如下:
mysql> delete from student where id not in (select min(id) from student group by name);
- H8 }7 N0 N2 \# |& A1 `执行报错:1093 - You can't specify target table 'student' for update in FROM clause
3 n* C0 l. ?8 _2 T1 j# g原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。; I9 P; z3 A+ `6 K0 O4 A
怎么规避这个问题?/ m, h1 ^" g2 P! s2 E2 `
再加一层封装,如下:
, U- e/ p' D9 _$ z" G. J4 m& lmysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);% W$ j9 R$ p8 }2 o3 Y2 s) @- E4 g1 `
Query OK, 3 rows affected
mysql> select * from student;
! B! O8 Z: D" W7 @+----+------+4 s4 B* r0 O6 _! s+ k
| ID | NAME |) D) t, V8 }, z( `* T; X: c: Z
+----+------+
3 V& Y, Y& O0 r2 ~$ y3 s0 M/ v& q| 11 | aa |) {. J" e; y' U4 F! O6 q( j' \, u
| 13 | bb |& f! u( E, X8 c9 a. N% [
| 16 | cc |$ r! D/ |" V0 v3 j' a8 P, Q
+----+------+
; h1 A/ Q# |  q% _! L3 rows in set
) p" W. ]$ ~4 O# L6 a+ A
方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);8 h" v- b3 o; T1 B. l' P5 a$ R/ D) P2 R. h

  B( {7 ^7 H: D  z# h% e$ S
1 S8 _; D9 x' |$ g' k1 f. V* \) w/ Y
回复

使用道具 举报

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

本版积分规则

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