SQL更新按排名顺序

时间:2018-06-28 10:08:06

标签: sql oracle11g

使用Oracle 11g,以及以下数据:

create  table ds_tmp
(col1 varchar2(5) ,date1 DATE, col3 varchar2(3));

insert into ds_tmp
values('pat1','01-JAN-2018','PND');

insert into ds_tmp
values('pat1','02-JAN-2018','MIS');

insert into ds_tmp
values('pat1','03-JAN-2018','DUP');

insert into ds_tmp
values('pat2','01-JAN-2017','MIS');

insert into ds_tmp
values('pat2','02-JAN-2017','DUP');

insert into ds_tmp
values('pat2','03-JAN-2017','DUP');

insert into ds_tmp
values('pat2','04-JAN-2017','INV');

我需要做的是: 1)按col1分组 2)按以下顺序更新col3:

if any col3=PND then set all col3 to PND
else if any col3=MIS set all col3 to MIS
else if any col3=DUP set all col3 to DUP
else set all col3 to INV

因此,使用上述数据,我们将得出pat1 = PND的所有col3值和pat2 = MIS的所有col3值。 如果可以的话,我可以使用CASE来模仿,但只能在1列上选择。我想我可能需要一个分析等级函数,但我想不出如何编码它,任何建议都值得赞赏。

1 个答案:

答案 0 :(得分:1)

您可以通过以下方式获得调整后的值:

select col1, date1, col3,
  case
    when count(case when col3 = 'PND' then col3 end)
           over (partition by col1) > 0 then 'PND'
    when count(case when col3 = 'MIS' then col3 end)
           over (partition by col1) > 0 then 'MIS'
    when count(case when col3 = 'DUP' then col3 end)
           over (partition by col1) > 0 then 'DUP'
  end as adj_col3
from ds_tmp;

COL1  DATE1       COL ADJ
----- ----------- --- ---
pat1  03-JAN-2018 DUP PND
pat1  02-JAN-2018 MIS PND
pat1  01-JAN-2018 PND PND
pat2  03-JAN-2017 DUP MIS
pat2  02-JAN-2017 DUP MIS
pat2  04-JAN-2017 INV MIS
pat2  01-JAN-2017 MIS MIS

然后将col3替换为查询中的该表达式,或者,如果您确实想更改表中的值,请使用该表达式进行更新。

over (partition by col1)进行“分组”部分,并且按照您想要的顺序评估这三个值,因此PND优先于MIS等。