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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2016-8-23 20:58:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
方法1:
% m% o* {. L! m- g' {9 o1、创建一个临时表,选取需要的数据。
  G. w0 x/ R8 J9 X6 L) J2 z6 T* o0 L2、清空原表。
% f! F/ g- S, I# G1 M* E3、临时表数据导入到原表。* i  b  N* S- A/ z
4、删除临时表。$ c* m) o, i2 x/ P$ n8 c  h
mysql> select * from student;! z) O& t: |+ Q$ O
+----+------+/ L8 L. R  J1 d" p, x
| ID | NAME |1 d' M  n; J# K3 a' f7 Q* b! V
+----+------+2 z3 D- k# ?( b; e9 O4 y
| 11 | aa |2 s$ d' J0 |* Z/ ~+ A, V: P1 s
| 12 | aa |' y1 `% J4 @) p' z- n6 P
| 13 | bb |+ N5 {5 `4 p3 b. W( f) p  ?: O# K
| 14 | bb |; I5 P2 M* K% f) G' x
| 15 | bb |
: P2 o! z, X$ R5 u, U+ D| 16 | cc |
4 j" ]: R1 D  c7 O1 j+----+------+
+ ^9 C; E2 m, [* j& V' M, F6 rows in set
mysql> create temporary table temp as select min(id),name from student group by name;% y5 ?2 A; B( C% z
Query OK, 3 rows affected- m9 I* p# q# V
Records: 3 Duplicates: 0 Warnings: 0
mysql> truncate table student;
' e" G$ T3 h; H# O  N5 lQuery OK, 0 rows affected
mysql> insert into student select * from temp;
, Y% Y- u4 Y4 a7 S' \/ f, q2 lQuery OK, 3 rows affected
5 U! B7 {" e+ m  N& e; _- C. iRecords: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;" t: }. p$ h3 K/ T+ l6 P& g, B
+----+------+
, N) N4 l! B" U2 n| ID | NAME |
0 f0 {* t  P3 c: H# h! _& d+----+------+% a5 U2 `6 m3 A% h4 c$ H3 K
| 11 | aa |
$ t5 ?1 x- O9 g2 Z8 C1 h| 13 | bb |
7 J" ?7 t2 @, b! r| 16 | cc |6 a  w0 H0 h- y6 |
+----+------+5 s! j* u) v5 g7 F
3 rows in set
mysql> drop temporary table temp;
- `, ]7 i0 q% r5 w- N/ [Query OK, 0 rows affected
7 @$ j- [# g* W' L" r# \. ?这个方法,显然存在效率问题。

方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:
6 O% s6 B' x- `6 Lmysql> create temporary table temp as select min(id) as MINID from student group by name;) o0 b2 E' }' r
Query OK, 3 rows affected
' N, Y/ \$ s" \& NRecords: 3 Duplicates: 0 Warnings: 0
mysql> delete from student where id not in (select minid from temp);
% o9 q/ j% d( Z* I; m+ r9 b6 z8 _Query OK, 3 rows affected
mysql> select * from student;3 R/ i7 V0 P" a2 l5 [
+----+------+( O; w0 h. _7 _+ H/ P8 [
| ID | NAME |+ j9 x# H# H+ h8 y/ E! x& t7 I$ C
+----+------+
2 A" |- ^7 k" a' I6 ?# Z! b" z| 11 | aa |
1 S( [8 O5 E1 D2 @/ ^! O1 ]# t| 13 | bb |  x8 Q% x4 j- y/ q6 P
| 16 | cc |
7 E( d* \* J- P# i0 t+----+------+
$ X3 s3 y3 I. {3 rows in set

方法3:直接在原表上操作,容易想到的sql语句如下:
mysql> delete from student where id not in (select min(id) from student group by name);. L' `% E/ d& j( u8 g
执行报错:1093 - You can't specify target table 'student' for update in FROM clause
4 {/ ?1 g4 @: J. e! ^( ]原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。
" R0 }# j& _9 [, ], h; v怎么规避这个问题?8 d3 U  i7 V% }% B6 W( O
再加一层封装,如下:6 B4 ?# ]+ ~' l) d: l6 `/ g' |
mysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);
! c8 Q. G9 c* b/ X# `7 Q& lQuery OK, 3 rows affected
mysql> select * from student;7 v9 H/ v- G* c' C
+----+------+
2 `! Y9 }, X8 r' b| ID | NAME |
" Q/ Q, _+ g# e& T$ q% f  L+ k+----+------+
$ @% W( o" k- ?6 D; a! R$ r| 11 | aa |/ e- n$ O) S% S( W7 i+ n
| 13 | bb |/ g, \! f6 P. G. D8 f
| 16 | cc |* _' Y* v) d. P8 M+ b1 u
+----+------+
7 e) A8 l( A+ i  u, B% j; J3 rows in set

4 A# l$ H1 k  `) w$ V4 E方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);% O, d2 ~% P  d) W) ?  I- p, Z0 h4 k
9 v8 ~3 [$ \1 _* N) g- ]
; z2 h7 J7 u' i4 E9 U, G. m3 ^
回复

使用道具 举报

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

本版积分规则

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