仅更新一定数量的记录

时间:2019-05-15 13:46:55

标签: oracle

需要更新一定数量的行,并且ID可以有很多结果。

TABLE1

ID      PHONE        INCLUDE
123456  5071239898  
789012  8765242301  
789012  9855468712  
888777  7635072525  
999999  6121234567  
999999  9526544567  

我需要做的是总共选择2条唯一记录,但包括所有结果。

因此,在更新/选择后:

ID      PHONE        INCLUDE
123456  5071239898   YES    
789012  8765242301   YES    
789012  9855468712   YES    
888777  7635072525   NO
999999  6121234567   NO
999999  9526544567   NO

1 个答案:

答案 0 :(得分:1)

您可以使用dense_rank()函数为每一行分配一个等级编号,该编号对于具有相同ID的所有行都是相同的-通过在ID列上进行分区。

select id, phone, include, dense_rank() over (order by id) as rnk
from table1;

        ID      PHONE INC        RNK
---------- ---------- --- ----------
    123456 5071239898              1
    789012 8765242301              2
    789012 9855468712              2
    888777 7635072525              3
    999999 6121234567              4
    999999 9526544567              4

,然后使用大小写表达式将这些排名转换为是/否:

select id, phone,
  case when dense_rank() over (order by id) < 3 then 'YES' else 'NO' end as include
from table1;

        ID      PHONE INC
---------- ---------- ---
    123456 5071239898 YES
    789012 8765242301 YES
    789012 9855468712 YES
    888777 7635072525 NO 
    999999 6121234567 NO 
    999999 9526544567 NO 

如果您想更新原始表-这可能不是一个好主意,因为它将过时;一个进行计算的视图可能会更好-那么您可以在合并中使用相同的机制:

merge into table1 t
using (
  select rowid, dense_rank() over (order by id) as rnk
  from table1
) s
on (s.rowid = t.rowid)
when matched then
update set t.include = case when s.rnk < 3 then 'YES' else 'NO' end;

6 rows merged.

select * from table1;

        ID      PHONE INC
---------- ---------- ---
    123456 5071239898 YES
    789012 8765242301 YES
    789012 9855468712 YES
    888777 7635072525 NO 
    999999 6121234567 NO 
    999999 9526544567 NO 

db<>fiddle

对问题发表评论后:

select count(*), count(distinct id) from TABLE1 where include = 'YES';

  COUNT(*) COUNT(DISTINCTID)
---------- -----------------
         3                 2