中国网络渗透测试联盟

标题: mysql删除重复记录,保存Id最小的一条 [打印本页]

作者: admin    时间: 2016-8-23 20:58
标题: mysql删除重复记录,保存Id最小的一条
方法1:
9 s) }& T( Q. t0 d: {1、创建一个临时表,选取需要的数据。& C% t3 z, F" L# y* E( v, T
2、清空原表。
2 }. I3 ?( e5 k1 ?+ L3 s) }0 ~4 o3、临时表数据导入到原表。
5 L1 d, @& B+ g, M7 g4、删除临时表。
# G0 G4 S5 n* o; b: I, `9 e# M5 rmysql> select * from student;
* }6 s+ d4 H8 o; J$ ~9 \; G2 F+----+------+' A' o: c  Y5 h/ [
| ID | NAME |$ [0 ?  ?9 M0 B
+----+------+) F* C2 ]) y4 V
| 11 | aa |
% U8 R% a- T! _| 12 | aa |* o3 Y- A* o' b# \5 }
| 13 | bb |6 q  P2 |( _) @
| 14 | bb |
' y# z! o8 o) }" h| 15 | bb |" O! I0 v0 b- L% T
| 16 | cc |# E5 x2 r) c" Y9 R- @. h( y2 c
+----+------+
4 a* S' X2 t% ^& V& X& k/ K6 rows in set
mysql> create temporary table temp as select min(id),name from student group by name;
& {2 I$ I& G% U6 Q. \- h  UQuery OK, 3 rows affected3 L7 m# f! {$ f2 a- P) V
Records: 3 Duplicates: 0 Warnings: 0
mysql> truncate table student;
. P8 d8 X, P; i- T' gQuery OK, 0 rows affected
mysql> insert into student select * from temp;
' R; X, V1 V5 l" m& v7 `+ XQuery OK, 3 rows affected7 z1 H' O9 Z) I: @
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;
# Q: ^$ o2 Q7 z+----+------+
8 d/ ?: ~6 F# f* H9 v. e, i| ID | NAME |7 s8 A* U" m( y& s$ g: n
+----+------+
' i; W* U% W0 `" t- D; G3 T| 11 | aa |
! B7 }4 R4 d1 T: `- G5 C/ x| 13 | bb |
: U) e. p1 Z% p5 {' D4 _2 q1 a| 16 | cc |
2 S6 d- b6 B# L. Z# q+----+------+
$ e; I; i7 D/ C3 rows in set
mysql> drop temporary table temp;
* Z6 w% e# |2 X* rQuery OK, 0 rows affected
& _% s# u; C/ u' y2 u: |/ D这个方法,显然存在效率问题。

方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:' P) N* I6 R% m. Z3 K
mysql> create temporary table temp as select min(id) as MINID from student group by name;+ Q9 ^' n' U2 U) y2 Q
Query OK, 3 rows affected, r. @/ m! E0 C" i. K# }
Records: 3 Duplicates: 0 Warnings: 0
mysql> delete from student where id not in (select minid from temp);+ I0 N( q# w/ q% X  o
Query OK, 3 rows affected
mysql> select * from student;; K/ l4 M0 k# d# I5 c, c* b
+----+------+- [0 r9 j9 i9 E" n6 o& `  u
| ID | NAME |6 E: j4 z% D: z* L( J
+----+------+6 v. M2 o! [: n3 r. {6 t
| 11 | aa |* B2 c% I: @- w2 R
| 13 | bb |
+ k3 S. v* S+ R8 G| 16 | cc |
* r* h' w# O2 ?0 L+----+------+
8 b4 ^+ L5 r* c( O3 rows in set

方法3:直接在原表上操作,容易想到的sql语句如下:
mysql> delete from student where id not in (select min(id) from student group by name);
$ L% K3 e5 v7 u0 `7 f3 ]4 P执行报错:1093 - You can't specify target table 'student' for update in FROM clause$ J, I0 m  S% g# B2 C% J
原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。/ a- R# ~5 c) V" p# ]; B1 m
怎么规避这个问题?
( e# s, ~! \, E; [5 o再加一层封装,如下:
1 k; f& a9 a& y; Hmysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);
! U2 f7 a+ M8 x6 q  rQuery OK, 3 rows affected
mysql> select * from student;9 k" k: Q1 e% {4 g5 t( ]4 S1 B  n% _, l
+----+------+: G4 z: q+ Y  R' q1 o+ V
| ID | NAME |
# c" _0 m4 p8 Z5 M! S. k% q. S3 U+----+------+0 x# R7 k5 }' k) Z! ?& F: x
| 11 | aa |
& x+ R1 i  ^9 ?" B| 13 | bb |6 ^4 D) s5 Y( W  c6 P
| 16 | cc |
" o( |) v: T( S7 [& g+----+------+; C/ h5 {$ F2 Y% N+ P
3 rows in set

/ s& p; @) ?+ n9 d( `方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);0 [7 K4 i+ U5 C' w7 @
4 b: N" K4 O3 ~1 [! k6 f
# L7 g. K9 Y0 I+ p





欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) Powered by Discuz! X3.2