Oracle query eliminate duplicates not considering Null

时间:2019-03-19 14:58:51

标签: sql oracle

I've performed a full outer join where I get the following:

ColumnFromTable1          ColumnFromTable2
     AAA                       ABA
     AAA                       Null          <-  remove
     AAA                       ACC
     BBB                       Null
     CCC                       CDC
     Null                      EFE
     DDD                       FFF
     Null                      FFF           <-  remove
     GGG                       FFF

What I really want is to squash down the rows to remove duplicates such that my results would be:

ColumnFromTable1          ColumnFromTable2
     AAA                       ABA
     AAA                       ACC
     BBB                       Null
     CCC                       CDC
     Null                      EFE
     DDD                       FFF
     GGG                       FFF

Basically I need to eliminate

AAA  Null
Null  FFF

since I have an AAA or FFF with a non-null. But I need to keep

BBB  Null
Null  EFE

because there is no BBB or EFE with a non-null

I've tried modifying my full outer join (which I can post if need be) and also tried wrapping these results in a sub query.

EDIT here is the query simplified for this post

select ColumnFromTable1, ColumnFromTable2 from Table1 t1
       full outer join Table2 t2 on t1.common_code = t2.common_code 
       group by ColumnFromTable1, ColumnFromTable2 

2 个答案:

答案 0 :(得分:3)

row_number()看起来很有希望:

select c1, c2
  from (
    select c1, c2, 
           row_number() over (partition by c1 order by c2) r1,
           row_number() over (partition by c2 order by c1) r2
      from t)
  where not ((c1 is null and r2 > 1) or (c2 is null and r1 > 1))

demo

当空值不是按顺序排列时,它将消除空值。

答案 1 :(得分:0)

Placing the full outer join you already computed in a CTE, you can filter it further as you want by doing:

with f (c1, c2) as (
  ... -- full outer join you already computed here
)
a (x) as ( -- repeated c1 with non-null c2
  select c1
  from f
  group by c1
  having count(c2) > 0
),
b (x) as ( -- repeated c2 with non-null c1
  select c2
  from f
  group by c2
  having count(c1) > 0
)
select *
from f
where not(c1 in (select x from a) and c2 is null)
  and not(c2 in (select x from b) and c1 is null)