我有一个表预订,每个电话号码都有重复的行
+----+------+-----+--- | 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
答案 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;