Oracle自联接将列值复制到同一列中的不同值

时间:2016-01-12 17:36:00

标签: sql oracle join self-join

我有一些近乎重复的数据,我正在尝试清理。我正在进行自我连接以查找除了其中一列之外的所有列都相同的记录,因此我可以找到从表中删除的最佳重复项。我遇到的问题是虽然数字记录是正确的,但我只是看到一个id列值反复重复。当我查看与此用户关联的所有值时,只会出现一次正在重复的id列值。

我知道这并不完全清楚,所以希望这会有所帮助。

Id1    ID2    AnotherColumn    AnotherColumn2
---------------------------------------------

1      345       "a"                "bd"
2      345       "a"                "bd"
3      345       "a"                "bd"
4      345       "a"                "bd"
5      345       "a"                "bd"

我想要回来的就是你在这个虚拟表中看到的一切。我得到的是:

Id1    ID2    AnotherColumn    AnotherColumn2
---------------------------------------------

1      345       "a"                "bd"
1      345       "a"                "bd"
1      345       "a"                "bd"
1      345       "a"                "bd"
1      345       "a"                "bd"

我使用的查询如下所示:

select A.Id1, A.ID2, A.AnotherColumn, A.AnotherColumn2
from dummy_table A, dummy_table B
where A.ID2 = B.ID2
AND A.Id1 <> B.Id1
AND A.AnotherColumn = B.AnotherColumn
AND A.AnotherColumn2 = B.AnotherColumn2

我想知道的是为什么Id1的值被复制到其他行而不是实际显示的原始Id1值。

我需要在此表中列出符合这些条件的ID列表,因为我必须将它们从原始表中删除,原始表中包含的其他记录与这些标准不匹配,需要保持不变。

2 个答案:

答案 0 :(得分:1)

我认为这会做你想做的事情:

select min(A.id) over (partition by A.ID2, A.AnotherColumn, A.AnotherColumn2) as id,
       A.id2, A.AnotherColumn, A.AnotherColumn2
from dummy_table A;

这会返回id子句中列组合的最小partition by

答案 1 :(得分:1)

当我运行您的查询时,我最终得到20行; 4为每个id1值(与4 x 5相同,因为您实际上是在进行交叉连接,只排除a.id1 = b.id1的行。)

with dummy_table as (select 1 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual union all
                     select 2 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual union all
                     select 3 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual union all
                     select 4 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual union all
                     select 5 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual)
select A.Id1, A.ID2, A.AnotherColumn, A.AnotherColumn2
from dummy_table A, dummy_table B
where A.ID2 = B.ID2
AND A.Id1 <> B.Id1
AND A.AnotherColumn = B.AnotherColumn
AND A.AnotherColumn2 = B.AnotherColumn2
order by 1, 2, 3, 4


       ID1        ID2 ANOTHERCOLUMN ANOTHERCOLUMN2
---------- ---------- ------------- --------------
         1        345 a             bd            
         1        345 a             bd            
         1        345 a             bd            
         1        345 a             bd            
         2        345 a             bd            
         2        345 a             bd            
         2        345 a             bd            
         2        345 a             bd            
         3        345 a             bd            
         3        345 a             bd            
         3        345 a             bd            
         3        345 a             bd            
         4        345 a             bd            
         4        345 a             bd            
         4        345 a             bd            
         4        345 a             bd            
         5        345 a             bd            
         5        345 a             bd            
         5        345 a             bd            
         5        345 a             bd

但是,我想知道你是否喜欢这样的事情:

with dummy_table as (select 1 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual union all
                     select 2 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual union all
                     select 3 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual union all
                     select 4 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual union all
                     select 5 id1, 345 ID2, 'a' AnotherColumn, 'bd' AnotherColumn2 from dual union all
                     select 6 id1, 345 ID2, 'b' AnotherColumn, 'bd' AnotherColumn2 from dual)
select id1,
       id2,
       anothercolumn,
       anothercolumn2
from   (select id1,
               id2,
               anothercolumn,
               anothercolumn2,
               count(*) over (partition by id2, anothercolumn, anothercolumn2) cnt
        from   dummy_table)
where  cnt > 1;

       ID1        ID2 ANOTHERCOLUMN ANOTHERCOLUMN2
---------- ---------- ------------- --------------
         1        345 a             bd            
         2        345 a             bd            
         3        345 a             bd            
         4        345 a             bd            
         5        345 a             bd 

你可能根本不需要分析功能 - 要删除除id1最低的行以外的所有行,你可以这样做:

delete from dummy_table
where id1 not in (select min(id1) from dummy_table group by id2, anothercolumn, anothercolumn2);