【问题标题】:SQL: Removing Duplicate records - Albeit different kindSQL:删除重复记录 - 尽管类型不同
【发布时间】:2012-02-08 10:34:40
【问题描述】:

考虑下表:

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 解决方案。感谢您的每一次帮助。

【问题讨论】:

  • 您到底想完成什么?请对此进行扩展。
  • 我需要一个 SQL 来生成记录集 {1, 2, A}, {2, 3, C} 和 {3, 4, D}。对我来说 {1, 2, A} 和 {2, 1, A} 是重复记录,结果集应该只有一个元组({1, 2, A} 或 {2, 1, A},但不能同时包含)
  • 明确一点,“删除”是指从结果集中过滤而不是删除
  • @APC,你是对的。去除手段,在结果集中过滤。谢谢指正。

标签: sql oracle duplicate-data duplicate-removal


【解决方案1】:

使用 GREATEST() 和 LEAST() 函数来识别跨多个列的公共值。然后使用 DISTINCT 筛选出重复项。

select distinct least(a, b) as a
       , greatest(a, b) as b
       , c
from t6 

这将为您提供所需的精确记录集。但是,如果您需要包含 T6 中的其他列,事情会变得更加复杂。


“但我想知道这是否也适用于 VARCHAR2 字段?”

是的,但它会使用 ASCII 值来确定顺序,这并不总是您可能期望(或希望)的。

“另外,我的表T6可能有几万条记录。”

用今天的术语来说,这确实不是很多数据。 DISTINCT 将导致排序,除非 AB 是非常长的 VARCHAR2 列,否则它应该能够放入内存中 - 但即使这样也可能。

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

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

但我真的只会在您遇到真正的查询性能问题时才会打扰。

【讨论】:

  • 感谢@APC,我现在无法检查。但我想知道这是否也适用于 VARCHAR2 字段?另外,我的表 T6 可能有数万条记录。感谢您的回复,但 Stackoverflow 仍然不允许我投票给您。 :(
【解决方案2】:

如果A列和B列的顺序无关紧要并且总是包含一个整数,那么如何:

select distinct
  least(a, b) as a,
  greatest(a, b) as b,
  c
from
  t6

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-07
    • 2010-10-24
    • 1970-01-01
    • 2020-07-16
    • 2021-02-13
    • 2020-03-31
    • 1970-01-01
    相关资源
    最近更新 更多