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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2016-8-23 20:58:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
方法1:
  `( ^$ d9 L; v- G: a- k1、创建一个临时表,选取需要的数据。8 s: H2 `5 a8 e* _; j
2、清空原表。
! w% e$ y! @" \3、临时表数据导入到原表。
4 Q9 v9 u% }$ q% s4 n, \4、删除临时表。
6 S/ ]$ ~5 ?- b7 a+ cmysql> select * from student;3 `( {$ s! Z& w! ?( F( E
+----+------+
! _+ K0 X7 r8 G) B0 r+ y| ID | NAME |/ k2 v, J8 b, N1 c9 A) \( I1 Y
+----+------+: E  ~# }- M, H3 t, q# c
| 11 | aa |7 v" K6 _( {8 l  s7 }
| 12 | aa |, B3 m& T9 R" I* a0 x! \
| 13 | bb |
6 I6 z8 w8 Y& d9 k& q$ r| 14 | bb |) q. p: A- k* o/ N9 P* P  \
| 15 | bb |7 x0 M3 K  V7 G0 B( A3 E! |
| 16 | cc |
; }0 \; ?9 O1 O' K' @- {+----+------+) Z3 y$ z% h0 M* x
6 rows in set
mysql> create temporary table temp as select min(id),name from student group by name;
8 m  l% `1 x! G) YQuery OK, 3 rows affected, ~$ j. L9 g3 g; V
Records: 3 Duplicates: 0 Warnings: 0
mysql> truncate table student;
2 X/ l9 B: ?7 Y0 gQuery OK, 0 rows affected
mysql> insert into student select * from temp;5 p6 U8 g8 i# R2 p
Query OK, 3 rows affected0 E1 G) q% |- z& K. r8 _1 @
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;0 ?; K2 g. K( K1 ~8 e1 w
+----+------+
8 h7 `) U  d5 S3 \+ N; W| ID | NAME |
: {2 o# S' s& Q" L# F+----+------+( z2 B4 C$ ~- y2 U$ u5 G1 K$ o4 ~  b
| 11 | aa |
: B( H- x  l# d- s( P9 }| 13 | bb |- a# z. S0 J$ y2 _. U
| 16 | cc |
1 R& V/ _% }; i9 M0 i) ?+ |+----+------+* n- L* S" m! v0 k3 r
3 rows in set
mysql> drop temporary table temp;# w5 K, h: j% F# J6 |
Query OK, 0 rows affected* f. W# k9 \2 p' u( U' j+ w
这个方法,显然存在效率问题。

方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:9 v$ x( i  C6 W& y6 s1 }4 v
mysql> create temporary table temp as select min(id) as MINID from student group by name;
" z% e" t/ T: ?" a! ^Query OK, 3 rows affected# f6 M) b8 H' F& r, M$ P, a, u4 L
Records: 3 Duplicates: 0 Warnings: 0
mysql> delete from student where id not in (select minid from temp);
2 E" V+ n! d: \; X0 Q8 [Query OK, 3 rows affected
mysql> select * from student;# O( ?$ `1 m6 ]
+----+------+
; M7 o  K7 `! b+ Q, M/ ~, r' S  M' T; P| ID | NAME |2 e" b, \' B$ F; `0 F
+----+------+
" h" |& m& ^7 S, \" \| 11 | aa |
& Z& s" Y- Y7 {) K6 g# L| 13 | bb |0 G6 ~! h  G% s" i$ \, y& x
| 16 | cc |
7 C5 N' Y! x+ ]; H+ j7 ?: c+----+------+
( s! O( S- x) z& U+ j% w3 rows in set

方法3:直接在原表上操作,容易想到的sql语句如下:
mysql> delete from student where id not in (select min(id) from student group by name);
% c3 n% u9 j' R' U' ^8 \' |执行报错:1093 - You can't specify target table 'student' for update in FROM clause
& v! h& K9 p3 l4 Q$ d) f1 \原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。' n. \8 d& x9 e  W' ?+ ?: {1 W5 l! k
怎么规避这个问题?
4 Y' U  F0 `% V, e9 r, G再加一层封装,如下:
# L* T* N; M% E4 v; n) Cmysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);4 \, q9 u0 b" n) _- X. r# L  p
Query OK, 3 rows affected
mysql> select * from student;1 I# _9 v. ^4 m  R( n3 j" B
+----+------+
9 `3 p/ Q% y+ d5 B) T7 X* t1 t7 c| ID | NAME |. ?0 V' y8 I0 p$ q; C+ d
+----+------+
, l. o4 W" K% `1 ~| 11 | aa |% k! ]( B& Q7 F2 T# l1 B: t
| 13 | bb |
; ?+ K* C' A1 E0 T5 N| 16 | cc |0 h/ u6 l* Q. d6 h- L
+----+------+1 l: h# N" E: H% U
3 rows in set
' ~) i# U) C! }8 g* G+ R5 O) d
方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);+ l- t/ j, G/ U( X1 C
2 L6 ]* V9 a" E
5 Q; p9 s1 t% U$ Q1 ^
回复

使用道具 举报

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

本版积分规则

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