考虑下表:
TAB6
A B C
---------- ---------- -
1 2 A
2 1 A
2 3 C
3 4 D
我认为,记录{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
我尝试了以下查询。但无济于事。
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.
甚至这个:
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
两者都不起作用。
数据库将是Oracle 10g。寻找纯SQL解决方案。感谢每一位帮助。
答案 0 :(得分:6)
使用GREATEST()和LEAST()函数来识别多列中的公共值。然后使用DISTINCT来删除重复项。
select distinct least(a, b) as a
, greatest(a, b) as b
, c
from t6
这为您提供了所要求的精确记录集。但如果您需要包含T6中的其他列,事情会变得更复杂。
“但我想知道这是否也适用于VARCHAR2字段?”
是的但是它会使用ASCII值来确定顺序,这并不总是你所期望的(或期望的)。
“另外,我的桌子T6可能有数万条记录。”
在今天的条款中,真的不是很多数据。 DISTINCT将导致排序,除非A
和B
真的是长VARCHAR2列,否则它应该能够适合内存。
如果这是一个你想要运行很多的查询,那么你可以构建一个基于函数的索引来满足它:
create index t6_fbi on t6(least(a, b)
, greatest(a, b)
, c )
/
但如果您对查询有真正的性能问题,我真的很烦。
答案 1 :(得分:0)
如果A列和B列的顺序无关紧要并且始终包含整数,那么如何:
select distinct
least(a, b) as a,
greatest(a, b) as b,
c
from
t6