将自动增量列添加到按日期排序的现有表中

时间:2018-11-19 07:28:27

标签: postgresql sql-update ddl database-sequence

我在数据库中有一个名为“ tickets”的现有表,其中包含列:

id (string, Primary Key, contains UUID like e6c49164-545a-43a1-845f-73c5163962f2) 
date   (biginteger, stores epoch)
status (string)

我需要添加新的自动增量列 ticket_id ,但是要生成的值应根据“日期”列值。

我尝试过:

ALTER TABLE "tickets" ADD COLUMN "ticket_id" SERIAL;

问题在于,它正在以某种奇怪的顺序生成“ ticket_id”值,看起来它基于表的主键“ id”列。

是否可以生成根据“日期”排序的序列值?这很重要,因为需要根据票证的生成顺序显示“ ticket_id”。

1 个答案:

答案 0 :(得分:3)

如果添加这样的串行列,则现有行将以“任意”顺序自动更新。

要控制生成ID的顺序,您需要分多个步骤进行操作:

首先添加列,不添加默认值(serial表示默认值)

ALTER TABLE tickets ADD COLUMN ticket_id integer;

然后创建一个序列以生成值:

create sequence tickets_ticket_id_seq;

然后更新现有行

update tickets 
  set ticket_id = t.new_id
from (
   select id, nextval('tickets_ticket_id_seq') as new_id
   from tickets
   order by "date"
) t
where t.id = activities.id;

然后将序列设置为新列的默认值

alter table tickets alter column ticket_id set default nextval('tickets_ticket_id_seq');

最后,将序列与列关联(这也是serial在后​​台执行的操作):

alter sequence tickets_ticket_id_seq owned by tickets.ticket_id;

如果表真的很大(“数十”或“数百”),那么创建新表可能会更快:

create sequence tickets_ticket_id_seq;
create table tickets_new
as
select id, nextval('activities_ticket_id_seq') ticket_id, "date", status
from tickets
order by "date";

drop table tickets cascade;
alter table tickets_new rename to activities;
alter table tickets add primary key (id);
alter sequence tickets_ticket_id_seq owned by tickets.ticket_id;

然后重新创建该表的所有外键和索引。