SQL:去除重复记录-尽管不同类型

7
请看下面的表格:
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解决方案。非常感谢任何帮助。


你究竟想要实现什么?请详细说明。 - simchona
我需要一条SQL语句来生成记录集{1, 2, A},{2, 3, C}和{3, 4, D}。对于我来说,{1, 2, A}和{2, 1, A}是重复的记录,结果集应该只有一个元组(要么是{1, 2, A},要么是{2, 1, A},但不能同时存在)。 - G P
只是为了明确,您所说的“删除”是指从结果集中过滤而不是删除 - APC
@APC,你说得对。移除意味着在结果集中进行过滤。感谢纠正。 - G P
2个回答

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真的很长,否则应该可以放入内存 - 但即使如此。

如果这是您经常运行的查询,则可以构建一个基于函数的索引来满足它:

create index t6_fbi on t6(least(a, b)
                           , greatest(a, b)
                           , c )
/

但只有在您的查询真正存在性能问题时,才值得去烦恼。


谢谢@APC,我现在无法检查这个。但我想知道这个对VARCHAR2字段也适用吗?另外,我的表T6可能有成千上万条记录...感谢您的回复,但还不能在Stackoverflow上给您点赞。:( - G P

0
如果A和B列的顺序不重要且始终包含整数,那么如何处理:
select distinct
  least(a, b) as a,
  greatest(a, b) as b,
  c
from
  t6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接