中国网络渗透测试联盟

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

作者: admin    时间: 2016-8-23 20:58
标题: mysql删除重复记录,保存Id最小的一条
方法1:
1 x; F. W( `$ p# X9 g& d& s: t1、创建一个临时表,选取需要的数据。
' k! ?7 c! \1 s7 {% T2、清空原表。
2 T1 o; ?+ ]6 x  S$ k" |. Z) e3、临时表数据导入到原表。  X& u( f, ^  K' L/ V2 l# x
4、删除临时表。
+ j6 v0 p) m8 ~! k% hmysql> select * from student;
1 @2 O# \4 v5 a2 S: A+----+------+
; r8 {, \/ Q- t  h0 y$ G! t& s2 N| ID | NAME |
; J3 n1 ~9 S" j% Y+----+------+3 r8 a' h2 X8 k4 g9 ], H1 a* B. V% c, m: V
| 11 | aa |/ y6 i& Y: z- V& X/ J& `4 P% N9 X
| 12 | aa |
9 j. W4 q- C$ c; ?% `| 13 | bb |
" _) e  L/ G/ i9 K8 X| 14 | bb |
& n$ @. t' D3 {7 x/ E| 15 | bb |
* W5 P5 ^7 f2 b" U1 M* `% ?: u| 16 | cc |3 ~. ]0 a' t5 J4 o" F" N
+----+------+
) `; a- R. r9 j6 rows in set
mysql> create temporary table temp as select min(id),name from student group by name;
! p4 L0 t3 a' g% J+ MQuery OK, 3 rows affected
5 N, J% O; f1 a2 eRecords: 3 Duplicates: 0 Warnings: 0
mysql> truncate table student;1 o, W( K/ Q  l) R
Query OK, 0 rows affected
mysql> insert into student select * from temp;
( Y: \- V( T5 G9 I# q& QQuery OK, 3 rows affected
8 r. Y* v4 [. t. V! s8 h9 d* c/ tRecords: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;" ~2 z3 I9 ]1 x8 N' g# |5 X, _% _
+----+------+, c. h/ T" m- C; D- }3 q$ f
| ID | NAME |
" p% T5 B6 ?2 a& d+----+------+- \, b  S- J- ]; B) [+ J% f
| 11 | aa |9 V5 C; e- d: V" k4 b  Y
| 13 | bb |1 |1 Z7 y; ~5 \6 F; Z  e! ]& U" P6 B
| 16 | cc |
* g3 c. w1 J5 {2 N' k+----+------++ a& Q! l1 w6 l& l2 R6 F1 E5 l7 a
3 rows in set
mysql> drop temporary table temp;2 a: K) a6 |" Z1 b6 w  _; J
Query OK, 0 rows affected
% m2 _* y2 L% w2 D这个方法,显然存在效率问题。

方法2:按name分组,把最小的id保存到临时表,删除id不在最小id集合的记录,如下:
+ x3 m7 r8 X1 R9 |+ k* L3 Jmysql> create temporary table temp as select min(id) as MINID from student group by name;$ _  L2 w1 ^) d. P$ f/ G' M
Query OK, 3 rows affected/ P0 e7 O( D! b0 I
Records: 3 Duplicates: 0 Warnings: 0
mysql> delete from student where id not in (select minid from temp);
7 h2 _2 j& `% n: KQuery OK, 3 rows affected
mysql> select * from student;, t% ?/ @" B  M# A# C4 V& [. f8 ^
+----+------+
/ m: R5 o5 E3 p( k, i" n6 i+ O| ID | NAME |
" R0 ~3 T( K7 Q+----+------+. s( V' m5 l* a3 v% e
| 11 | aa |0 p& B: n* R( T2 S
| 13 | bb |+ k. `7 S5 L3 q; n, S4 B
| 16 | cc |
* o+ Y  W% S& |. e0 Z+----+------+, `- ^* j) ]: m: ~* k) l5 u/ Z1 _: A
3 rows in set

方法3:直接在原表上操作,容易想到的sql语句如下:
mysql> delete from student where id not in (select min(id) from student group by name);
' `5 F& P8 o6 s- }' K执行报错:1093 - You can't specify target table 'student' for update in FROM clause
( V' o  Y* A7 y6 ~0 Y2 Z原因是:更新数据时使用了查询,而查询的数据又做了更新的条件,mysql不支持这种方式。
: t. |7 u6 v! x6 F4 b怎么规避这个问题?  M! y* Q* z' p) H' l
再加一层封装,如下:
6 \0 P  j% g/ t% M' pmysql> delete from student where id not in (select minid from (select min(id) as minid from student group by name) b);
1 L( U8 M$ S  c3 ^, Z3 v% v  [9 XQuery OK, 3 rows affected
mysql> select * from student;3 @; y3 z  f9 A( L# _2 `
+----+------+4 b, h0 Z# l: F* E$ u/ w/ S
| ID | NAME |+ R* X/ q6 N9 P' o( o
+----+------+/ y* a4 f' X5 G5 Y  M# k
| 11 | aa |
! J1 C) X3 Z' u& ^1 w* Q, Y| 13 | bb |, W, @7 Y, L7 q9 o% O8 k8 ^
| 16 | cc |
8 U& W, Y! N) \$ ?+----+------+
  O/ ^# U" S0 F2 y3 rows in set

9 m' w3 _( d: S方法三例如:delete from bugdata where id not in (select minid from (select min(id) as minid from bugdata group by qxbh) b);
( f9 C1 G3 l' e! j9 e
7 o$ C& h/ n/ {. y: p0 C
* Z7 l, Q3 a+ j7 X  K




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