Oracle更新重复的行

时间:2018-07-26 10:00:34

标签: oracle

我有一个表预订,每个电话号码都有重复的行

+----+------+-----+---  
| id | phone | state |  
+----+------+-----+---  
| 1  | 1234  | 1     |  
| 2  | 1234  | 1     |  
| 3  | 1234  | 1     |   
| 4  | 5678  | 1     |  
| 5  | 5678  | 1     |  
| 6  | 5678  | 1     |  
+----+------+-----+----  

对于每个电话号码,我需要将状态列更新为-1(最后一个除外),按ID DESC排序。所以我的桌子应该变成

+----+------+-----+---  
| id | phone | state |  
+----+------+-----+---  
| 1  | 1234  | -1    |  
| 2  | 1234  | -1    |  
| 3  | 1234  |  1    |   
| 4  | 5678  | -1    |  
| 5  | 5678  | -1    |  
| 6  | 5678  |  1    |  
+----+------+-----+----  

我是oracle新手。有什么想法可以实现吗?我正在使用Oracle 11.2

2 个答案:

答案 0 :(得分:2)

您可以使用诸如rank()之类的分析函数来查找每个ID的新状态:

select id,
  case when rank() over (partition by phone order by id desc) = 1
       then 1 else -1 end as new_state
from subscription;

        ID  NEW_STATE
---------- ----------
         3          1
         2         -1
         1         -1
         6          1
         5         -1
         4         -1

然后在合并中使用它:

merge into subscription s
using (
  select id,
    case when rank() over (partition by phone order by id desc) = 1
         then 1 else -1 end as new_state
  from subscription
) t
on (s.id = t.id)
when matched then update set s.state = t.new_state
where s.state != t.new_state;

4 rows merged.

where s.state != t.new_state将停止在该行中更新其值已经正确的行,因此它仅合并了必须从1更改为-1的四行,而不是全部六行-并没有更新这两行并需要保留1的行。

select * from subscription;

        ID      PHONE      STATE
---------- ---------- ----------
         1       1234         -1
         2       1234         -1
         3       1234          1
         4       5678         -1
         5       5678         -1
         6       5678          1

这假设状态只能是1或-1 ...

答案 1 :(得分:0)

您可以使用更新语句

    UPDATE table_name s
    INNER JOIN
      (SELECT 
         MAX(id) id
         FROM
         table_name) smax ON s.id != smax.id 
SET 
state = -1;