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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2016-8-23 20:58:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
方法1:' z  @+ q8 I' F; P) ?/ d0 U
1、创建一个临时表,选取需要的数据。% W0 ]' J, J5 A/ \5 t1 V: K% B5 F9 o$ j& \
2、清空原表。
: t7 L0 n: S( I5 U  p6 w5 H/ T3、临时表数据导入到原表。
3 A3 \' L* z2 I, M* ]. f7 ?. e% F4、删除临时表。
# b7 v+ i+ @# s8 z; W$ Dmysql> select * from student;
8 A1 r, \. w* Y2 b+ i( G+----+------+# Q3 \" u$ ?2 x1 R
| ID | NAME |
  _- P" Q" p9 F5 n/ @  i1 q" r0 z, Z+----+------+
* f9 \0 ?  t& e4 L6 K) @2 i0 O| 11 | aa |
; ^/ M1 V) b0 f7 u! ?| 12 | aa |  D* z# t- F* V# Q" I  a& l/ R
| 13 | bb |
3 R. g$ l) R7 o2 e5 Q: O7 d+ Q| 14 | bb |
3 Q( D: `/ u' A0 E! Y/ ]/ y| 15 | bb |
) h3 T8 @. S( `4 V7 L* v| 16 | cc |& w! b( j3 T/ u# n9 N
+----+------+
5 b2 K3 J3 |7 R3 m5 M6 rows in set
mysql> create temporary table temp as select min(id),name from student group by name;6 G: x1 I0 @, n, c3 Y" [& }
Query OK, 3 rows affected
7 v! s) @; a" z& ?Records: 3 Duplicates: 0 Warnings: 0
mysql> truncate table student;2 ?- x& X; J9 s+ d1 Y; j
Query OK, 0 rows affected
mysql> insert into student select * from temp;$ ^' M0 t8 b: ?. i  ]
Query OK, 3 rows affected) i) M/ k  M! l5 {/ r
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;6 a+ t& H* L" Q/ v% z2 l+ {" ?8 I
+----+------+
. ~, H; M6 v# `0 J9 P8 t5 q3 R| ID | NAME |4 n# t" w% u% \1 w$ J
+----+------+1 X" x5 D7 l2 L7 y+ r9 V
| 11 | aa |: A, O* z" S! j; w/ A$ D/ |
| 13 | bb |
7 D$ d$ R! f& S$ F& k/ q$ X| 16 | cc |4 ?1 V3 Q5 F$ u* \/ c( X
+----+------+/ o5 e; [( m: x1 g" f' x! c
3 rows in set
mysql> drop temporary table temp;
! K* `9 }8 c$ g! \& Z& K( gQuery OK, 0 rows affected
6 V2 ^) q/ r6 R8 A这个方法,显然存在效率问题。

方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:
  u$ X2 e0 D' |* a* ]4 Hmysql> create temporary table temp as select min(id) as MINID from student group by name;
7 y0 n: h1 c; [: O: [( oQuery OK, 3 rows affected
& j% x- u8 p9 s! T6 i- }- DRecords: 3 Duplicates: 0 Warnings: 0
mysql> delete from student where id not in (select minid from temp);- N% L, k  t. m4 q: z& J/ K9 ^) W
Query OK, 3 rows affected
mysql> select * from student;' G0 I) s8 ^/ |( h
+----+------+" ~9 K. Z6 n% B9 L; B
| ID | NAME |' |9 s4 }; c' [) ^
+----+------+
: ~" u/ a1 X4 O; S1 I. c- c| 11 | aa |* L5 w8 }1 u0 ?: N
| 13 | bb |/ |! q1 `' b( \: x) l
| 16 | cc |
$ e& {8 Q( L* M/ z+----+------+; i  X) R% Z6 \% S3 W. @5 Q: C% W6 L
3 rows in set

方法3:直接在原表上操作,容易想到的sql语句如下:
mysql> delete from student where id not in (select min(id) from student group by name);
9 t5 b) J1 N1 O6 k执行报错:1093 - You can't specify target table 'student' for update in FROM clause
- c3 }% F) f0 Z; _& a原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。% V! m! S: ?% }& r
怎么规避这个问题?
( o4 j0 t$ p- Q再加一层封装,如下:
0 b3 P/ K& u+ \mysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);) F, f  \3 W! E/ ~2 J2 G9 o
Query OK, 3 rows affected
mysql> select * from student;
+ l: Z& t; D2 U+----+------+
7 |( q# d9 Z- n8 @6 E7 p| ID | NAME |/ v+ K0 }% z9 E7 c6 q
+----+------+5 a8 B5 L  Y9 D- O
| 11 | aa |
% I  j& ^8 s8 g| 13 | bb |0 _. z; N2 p+ _* K. n
| 16 | cc |
' b! I8 z6 c" x$ n+----+------+9 |4 M$ ?0 P5 x/ o7 k  [8 f
3 rows in set
4 [5 D# O) ^& Q6 c' x1 G
方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);' Q/ L8 z% e1 G* Y8 _- |9 z: w
8 z2 H0 }! i0 N
( B3 W& D1 u& y  B3 f* f
回复

使用道具 举报

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

本版积分规则

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