45

在 pgsql 中,有没有办法拥有一个包含多个值的表,并选择其中一个(例如 other_id),找出它的最高值是什么,并使放入表中的每个新条目都从该值递增。

我想这太容易了,没有机会工作..

ALTER TABLE address ALTER COLUMN new_id TYPE SERIAL

____________________________________ 
ERROR:  type "serial" does not exist

非常感谢您的任何见解!

4

3 回答 3

51

查看数据类型 serial的 postgresql 文档。串行只是短手。

CREATE TABLE tablename (
    colname SERIAL
);

相当于指定:

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
    colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
于 2013-05-10T03:35:15.867 回答
24

快速浏览一下文档会告诉你

数据类型 smallserial、serial和 bigserial不是真正的类型 ,而只是用于创建唯一标识符列的符号方便

如果您想让现有的(整数)列作为“序列”工作,只需手动创建序列(名称是任意的),将其当前值设置为当前值的最大值(或更大)address.new_id,在 set它作为您的address.new_id列的默认值。

要设置序列的值,请参见此处

SELECT setval('address_new_id_seq', 10000);

这只是一个示例,使用您自己的序列名称(任意,您创建它),以及一个大于您列的最大当前值的数字。


更新:正如卢卡斯的回答所指出的(这应该是被接受的),您还应该通过使用指定序列“属于”哪一列CREATE/ALTER SEQUENCE ... OWNED BY ...

于 2013-05-10T03:33:32.973 回答
24

发生这种情况是因为您只能在创建新表或向表中添加新列时使用串行数据类型。如果您尝试使用此数据类型更改现有表,则会收到错误消息。因为serial不是真正的数据类型,而只是更长查询的缩写或别名。

如果您想达到相同的效果,正如您在更改现有表时使用串行数据类型所期望的那样,您可以这样做:

CREATE SEQUENCE my_serial AS integer START 1 OWNED BY address.new_id;

ALTER TABLE address ALTER COLUMN new_id SET DEFAULT nextval('my_serial');
  1. 查询的第一行创建您自己的名为my_serial的序列。OWNED BY语句将 新创建的序列与表的确切列连接起来。在您的情况下,表是地址,列是new_idSTART语句定义了这个序列应该从什么值开始。

  2. 第二行使用新的默认值更改您的表,这将由先前创建的序列确定。

它将为您提供与使用串行所期望的相同的结果。

于 2019-01-14T20:52:12.163 回答