您需要先使用唯一的非空值更新现有行:
update the_table
set id = new_id
from (
select ctid,
(select max(id) from the_table) + row_number() over (order by date) as new_id
from the_table
where id is null
) t
where t.ctid = the_table.ctid;
我不确定使用这种方法是否能保证 ID 的顺序,但很可能确实如此。
现在,该列不包含任何 NULL 值,我们可以更改它自动分配新值。
接下来的步骤取决于您是想将其设为identity 列,还是仅将其设为具有序列默认值的列(本质上是 (discouraged) serial 列)
留在“连续剧”
我们需要创建一个序列并将其与列中的最大值同步。
create sequence the_table_id_seq;
select setval('the_table_id_seq', max(id))
from the_table;
然后将其用作默认值并将序列链接到列。
alter table the_table
alter id set not null,
alter id set default nextval('the_table_id_seq') ;
alter sequence the_table_id_seq owned by the_table.id;
使用identity 列(推荐)
要使其成为正确的(推荐)identity 列(Postgres 10 及更高版本),您可以这样做:
alter table the_table
alter id set not null,
alter id add generated always as identity;
现在添加身份属性创建了一个新序列,我们需要与列中的现有值同步:
select setval(pg_get_serial_sequence('the_table', 'id'), max(id))
from the_table;
或者,您可以手动查找当前最大值并在指定 identity 默认值时直接提供:
alter table the_table
alter id set not null,
alter id add generated always as identity (start with 42);