G P*_*G P 7 sql oracle duplicate-data duplicate-removal
请考虑下表:
TAB6
A B C
---------- ---------- -
1 2 A
2 1 A
2 3 C
3 4 D
Run Code Online (Sandbox Code Playgroud)
我认为,记录{1,2,A}和{2,1,A}是重复的.我需要选择并生成以下记录集:
A B C A B C
---------- ---------- - ---------- ---------- -
1 2 A or 2 1 A
2 3 C 2 3 C
3 4 D 3 4 D
Run Code Online (Sandbox Code Playgroud)
我尝试了以下查询.但无济于事.
select t1.*
from t6 t1
, t6 t2
where t1.a <> t2.b
and t1.b <> t2.a
and t1.rowid <> t2.rowid
/
A B C
---------- ---------- -
1 2 A
2 1 A
2 1 A
2 3 C
3 4 D
3 4 D
6 rows selected.
Run Code Online (Sandbox Code Playgroud)
甚至这个:
select *
from t6 t1
where exists (select * from t6 t2 where t1.a <> t2.b and t1.b <> t2.a)
/
A B C
---------- ---------- -
1 2 A
2 1 A
2 3 C
3 4 D
Run Code Online (Sandbox Code Playgroud)
两者都没用.
该数据库将是Oracle 10g.寻找纯SQL解决方案.感谢每一位帮助.
使用GREATEST()和LEAST()函数来标识多列中的公共值.然后使用DISTINCT来删除重复项.
select distinct least(a, b) as a
, greatest(a, b) as b
, c
from t6
Run Code Online (Sandbox Code Playgroud)
这为您提供了所要求的精确记录集.但是如果您需要包含T6中的其他列,事情会变得更复杂.
"但我想知道这对VARCHAR2字段是否也适用?"
是的,但它将使用ASCII值来确定顺序,这并不总是您可能期望(或期望).
"另外,我的桌子T6可能有数万条记录."
在今天的条款中,这真的不是很多数据.DISTINCT将导致一个排序,它应该能够适应内存,除非A并且B实际上是很长的VARCHAR2列 - 但可能甚至是这样.
如果这是一个你想要运行很多的查询,那么你可以构建一个基于函数的索引来满足它:
create index t6_fbi on t6(least(a, b)
, greatest(a, b)
, c )
/
Run Code Online (Sandbox Code Playgroud)
但如果您对查询有真正的性能问题,我真的很烦.