如何基于两列值的组合获取唯一行

时间:2019-04-25 10:27:33

标签: sql oracle

我有一个表,该表由带有值的以下字段组成

STAFFNO NAME DESGN DEPTT SPOUSE_STAFFNO SPOUSE_NAME SPOUSE_DESGN SPOUSE_DEPTT
111111  AAA  AM    HR    999999         PPP         JM           FIN
222222  BBB  DM    MKTG  888888         QQQ         AM           HR
333333  CCC  SM    FIN   777777         RRR         DM           FIN
999999  PPP  JM    FIN   111111         AAA         AM           HR
888888  QQQ  AM    HR    222222         BBB         DM           MTKG
777777  RRR  DM    FIN   333333         CCC         SM           FIN

我需要在Oracle中编写一个SQL查询,以获取雇员及其配偶的列表,而没有任何重复的行。从表中的值可以看出,表中存在的记录是针对每位唯一雇员的,它会重复为配偶输入。

考虑到雇员列表,我需要以下输出,以便如果针对任何雇员提供了配偶详细信息,则不应将配偶作为雇员再次在输出中重复相同的内容。

STAFFNO NAME DESGN DEPTT SPOUSE_STAFFNO SPOUSE_NAME SPOUSE_DESGN SPOUSE_DEPTT
111111  AAA  AM    HR    999999         PPP         JM           FIN
222222  BBB  DM    MKTG  888888         QQQ         AM           HR
333333  CCC  SM    FIN   777777         RRR         DM           FIN

请为所需的输出建议SQL代码。 任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:0)

使用相关子查询

select distinct t1.* from table t1
where not exists ( select 1 from table t2 where t1.STAFFNO=t2.SPOUSE_STAFFNO)

答案 1 :(得分:0)

我没有测试过,但是您可以尝试以下方法:

select * from table t where t.STAFFNO = t.SPOUSE_STAFFNO;

答案 2 :(得分:0)

这是一种适用于您的数据的方法:

select t.*
from t
where t.staffno < t.spouse_staffno;

但是,这假定所有对都在数据中。让我假设情况并非如此。在这种情况下:

select t.*
from t
where t.staffno < t.spouse_staffno
union all
select t.*
from t
where t.staffno > t.spouse_staffno and
      not exists (select 1
                  from t t2
                  where t2.staffno = t.spouse_staffno and
                        t2.spouse_staffno = t.staffno
                 );

您还可以使用单个语句和窗口函数来完成此操作:

select t.*
from (select t.*,
             row_number() over (partition by least(staffno t.spouse_staffno), greatest(staffno,  t.spouse_staffno)
                                order by staffno
                               ) as seqnum
      from t
     ) t
where seqnum = 1;

答案 3 :(得分:0)

不存在:

select t.* 
from tablename t
where not exists(
  select 1 from tablename 
  where
    STAFFNO < t.STAFFNO
    and 
    STAFFNO = t.SPOUSE_STAFFNO
)

答案 4 :(得分:0)

有点奇怪的要求...可能表示设计问题。

with your_data (STAFFNO,NAME,DESGN,DEPTT,SPOUSE_STAFFNO,SPOUSE_NAME,SPOUSE_DESGN,SPOUSE_DEPTT)
as
(select 111111, 'AAA','AM',  'HR',999999,'PPP','JM', 'FIN' from dual union all
 select 222222, 'BBB','DM','MKTG',888888,'QQQ','AM',  'HR' from dual union all
 select 333333, 'CCC','SM', 'FIN',777777,'RRR','DM', 'FIN' from dual union all
 select 999999, 'PPP','JM', 'FIN',111111,'AAA','AM',  'HR' from dual union all
 select 888888, 'QQQ','AM',  'HR',222222,'BBB','DM','MTKG' from dual union all
 select 777777, 'RRR','DM', 'FIN',333333,'CCC','SM', 'FIN' from dual)
select *
from (
select t1.staffno, t1.name, t1.desgn, t1.deptt, t2.staffno spouse_staffno, t2.name spouse_name, t2.desgn spouse_degn, t2.deptt spouse_deptt
,      row_number() over (partition by (coalesce(least(t1.staffno,t2.staffno),t1.staffno)) order by t1.staffno) rn
from   your_data t1
,      your_data t2
where  t2.staffno (+) = t1.spouse_staffno)
where rn = 1;

   STAFFNO NAM DE DEPT SPOUSE_STAFFNO SPO SP SPOU         RN
---------- --- -- ---- -------------- --- -- ---- ----------
    111111 AAA AM HR           999999 PPP JM FIN           1
    222222 BBB DM MKTG         888888 QQQ AM HR            1
    333333 CCC SM FIN          777777 RRR DM FIN           1