我有一个表格包含以下带有值的字段
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代码。任何帮助将受到高度赞赏。
使用相关子查询
select distinct t1.* from table t1
where not exists ( select 1 from table t2 where t1.STAFFNO=t2.SPOUSE_STAFFNO)
我没有测试它,但你可以尝试这样的事情:
select * from table t where t.STAFFNO = t.SPOUSE_STAFFNO;
以下是一种适用于您的数据的方法:
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;
使用NOT EXISTS:
select t.*
from tablename t
where not exists(
select 1 from tablename
where
STAFFNO < t.STAFFNO
and
STAFFNO = t.SPOUSE_STAFFNO
)
有点奇怪的要求......可能表明设计问题。
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