给出这样的表:
+----+-----
| id | ...
+----+-----
| 4 | foo
| 2 | bar
| 7 | baz
| 5 | gux
| . | ...
| . | ...
| . | ...
| |
我想为其中的所有记录分配新的ID,以便它们构建序列
an = an-1 + 1; a0 = x
我在哪里定义x
。
所以例如随着x
设为8
,桌子就会变成
+----+-----
| id | ...
+----+-----
| 8 | foo
| 9 | bar
| 10 | baz
| 11 | qux
| . | ...
| . | ...
| . | ...
| |
UPDATE
语句如何?
但是,如果您正在为测试或非常具体的任务执行此操作,并且您知道可能存在的问题,则可以使用以下序列执行此操作:
例如:x = 2000
CREATE SEQUENCE myseq START 2000;
update mytable set id = nextval('myseq');
显然你会失去原来的id命令。
我可以看到这对于其他用例非常难以预测,我同意@mnesarco的设计评论。总而言之,这是一个解决方案,可能会执行您在问题中描述的内容:
with baz as (
select
id, bar,
row_number() over (order by 1) as rn,
max (id) over (partition by 1) as max_id
from
foo
)
update foo
set
id = baz.max_id + baz.rn
from baz
where
foo.id = baz.id
我有一个真正的警告是,这就是说“按行排序行”(解析函数中的order by 1
),这是一件非常奇怪的事情。由于PostgreSQL使用MVCC进行DML的方式,单个更新将使该行“结束”到表的末尾。订单永远不是隐含的,因此除非您明确告诉它为什么这些ID按顺序排列,否则无法保证这将按您希望的方式分配ID。如果有一些我们可以隐式排序的列或列,我会感觉好多了 - 那么我会对你的问题采用这种方法感觉很好。