回答

收藏

SQL:删除重复的记录-尽管是另一种

技术问答 技术问答 193 人阅读 | 0 人回复 | 2023-09-14

请考虑下表:
1 G) s, v. J1 J  z" X& M' cTAB6
* h( g+ l+ O# z6 Y2 |( u& q6 Y         A          B C
& z3 {6 p/ [* a  L% E3 V---------- ---------- -
; E& u) u/ L: u- s         1          2 A
6 M% `1 q( Q/ ?" u2 j         2          1 A& a0 n, }) ?7 x# p* {, ~2 D
         2          3 C
5 j6 g2 m6 W0 t% A, `2 {, R% ?! ?         3          4 D
: \7 E8 [8 s  R# w. T我认为记录{1,2,A}和{2,1,A}是重复的。我需要选择并产生以下记录集:
8 o, b( w; ~, C; \* R% L' o         A          B C                      A          B C) F" e: E& q+ B) I( l
---------- ---------- -             ---------- ---------- -
  i6 g# I  G8 y+ ]7 |8 L         1          2 A         or           2          1 A
+ D+ f9 k: `9 z6 I" e2 \" Z         2          3 C                      2          3 C
" H. R1 ?2 @/ a         3          4 D                      3          4 D
0 y9 y/ ]0 G* j$ D7 l5 q6 A' G( |我尝试了以下查询。但无济于事。
9 o" f, {4 |! w- p% D" \) ?select t1.*6 s$ V' H" [; B2 A' J/ m
from t6 t1
! m4 u. S4 j, C6 M( W9 U4 s( ~8 _% b, t6 t25 b. R$ E0 H6 `( H
where t1.a  t2.b
/ v" Q% _. I& ?; [0 E0 T  `0 jand t1.b  t2.a3 \1 m" c& `5 F8 I6 Y
and t1.rowid  t2.rowid
7 `8 S* a2 \. d& D2 a! U& i; t/* i5 X& w4 g% O
         A          B C* v4 S" s+ g+ T- X
---------- ---------- -" f9 |$ @; d( S, ^- o6 T8 n
         1          2 A
3 t/ t, D! O: L+ K9 D) j) y         2          1 A6 E; x0 k& w& D3 s' ~- b
         2          1 A
7 H. ^" f2 ~* u$ U# J" p4 ~1 s8 t         2          3 C
8 b% C; {- s6 e& q6 Y& ?4 S$ L3 G         3          4 D3 ]1 o+ F% b% _) w
         3          4 D" c4 b5 ~2 h% _7 B1 S
6 rows selected.
- k# ?" M3 d+ ?甚至这个:; _- N. y! D3 T: m6 g
select *$ k% g0 {% Q. ?0 U  x0 N. Z  ~
from t6 t1! ~" W! q7 W" x# {
where exists (select * from t6 t2 where t1.a  t2.b and t1.b  t2.a)
: @* ]. s  V# B5 ^; X9 _3 ~5 g2 P8 c/& ]3 Z  N; I% F* d6 p/ k. W' w& P3 W. K
         A          B C
1 C4 v) C3 c' O, s; h/ N  ?# D---------- ---------- -4 g8 o$ U$ Q9 |- {
         1          2 A
7 b$ z# ]& X; `4 T' [# q, L         2          1 A
' Q0 C: ?* H9 C         2          3 C
: ?' g; A# D) o5 a( V         3          4 D
* R: k3 Z6 J/ L4 z4 M+ w$ D" \两者都不起作用。
- S1 }. r; p) K' B0 Y该数据库将为Oracle 10g。寻找纯SQL解决方案。感谢您的帮助。1 g* O- x. m+ |$ c) \1 m1 Q
                0 L2 q) t; }' T/ b- V" i
解决方案:0 k( {; w  a" B2 C+ J4 O( s5 n
                . i  Y6 g, w0 t+ X' A1 p/ p3 v3 K/ w' H) N

5 v4 d# y: _9 ^* k; Q2 V/ g
+ |: K. e: {  e. l" z" ]7 V# T                使用GREATEST()和LEAST()函数来识别多个列中的公共值。然后使用DISTINCT清除重复项。
! a2 W* L+ s) ]3 @. |8 wselect distinct least(a, b) as a2 d) K6 y1 [3 }3 y- ~5 D
       , greatest(a, b) as b
5 z. z  _: p' s7 a# l       , c
3 Y" L2 o! v: ?+ w! L: C1 afrom t6. m( Q  |$ T; D' n6 W0 J
这样可以为您提供精确的记录集。但是,如果您需要包括T6中的其他列,事情将会变得更加复杂。, h7 r7 d+ O6 l* c+ \
* g& {' U! |; S
“但是我想知道这是否也适用于VARCHAR2字段?”
2 A$ k2 }& z; ~4 f: U
% P6 _/ @# @! k3 a是的,但是它将使用ASCII值来确定顺序,这并不总是您可能期望的(或期望的)。
7 x# e, a4 w1 _
1 G5 R! C' |: U* {; e, {“此外,我的表T6可能有数万条记录。”  d& o# ~( {: i( {7 N7 d. J
: q% ?& a0 h/ W5 G4 Y
从今天的角度来看,这确实不是很多数据。该DISTINCT会引起一种,它应该能够装入内存,除非A与B有很长的VARCHAR2列-但可能即使这样。
7 `; P/ k8 |' ?: e# w如果这是您要大量运行的查询,则可以构建基于函数的索引来满足它:
4 z  w; O' e9 |- E! ^  kcreate index t6_fbi on t6(least(a, b)5 }7 }& b( Z9 T# r: R1 X' W
                           , greatest(a, b). y8 L0 l, U& z
                           , c )
4 j. q+ V* V% V/ H+ T- s8 L9 @/# @; b7 D0 M) _6 ~$ F! X
但是,如果您对查询有真正的性能问题,我真的只会打扰。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则