自動インクリメントの主キーをPostgreSQLの既存のテーブルに追加する方法は?


190

既存のデータを含むテーブルがあります。テーブルを削除して再作成せずに主キーを追加する方法はありますか?

回答:


354

更新-コメントした人々に感謝

PostgreSQLの最新バージョン

という名前のテーブルがありtest1、それに自動インクリメントの主キーid(サロゲート)列を追加するとします。最近のバージョンのPostgreSQLでは、次のコマンドで十分です。

   ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

PostgreSQLの古いバージョン

PostgreSQLの古いバージョン(8.xより前?)では、すべての厄介な作業を行わなければなりませんでした。次の一連のコマンドでうまくいくはずです。

  ALTER TABLE test1 ADD COLUMN id INTEGER;
  CREATE SEQUENCE test_id_seq OWNED BY test1.id;
  ALTER TABLE test ALTER COLUMN id SET DEFAULT nextval('test_id_seq');
  UPDATE test1 SET id = nextval('test_id_seq');

繰り返しますが、Postgresの最近のバージョンでは、これは上記の単一のコマンドとほぼ同じです。


3
私はORACLEを使用しているので、それを共有することはORACLEの人にとって役立つかもしれません。TEST1セットIDの更新= TEST1_SEQ.NEXTVAL; ALTER TABLE TEST1 ADD PRIMARY KEY(ID); UPDATEステートメントを実行する前にシーケンスTEST1_SEQを作成する
msbyuva

ADD PRIMARY KEYまた、作成しNOT NULLた制約は期待して欲しかったとして(postgresの9.3でテスト)。
Jared Beck

19
Postgresでは、単一のコマンドを使用できますALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
resnyanskiy '20

1
@resnyanskiyのコメントに加えて、これはテーブルにデータがある場合でも機能します。IDが入力され、null以外の制約が設定されます。回答全体をそのコメントの行で置き換えることができます。
Synesso、2015年

1
@EricWangありがとう、エリック、そうです-これはいくつかのバージョン(数年前)では機能しなかったと思いますが、よくわかりません。答えをコミュニティウィキに変えました。
leonbloy、

57
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

これはあなたがする必要があるすべてです:

  1. id列を追加する
  2. 1からcount(*)までのシーケンスを設定します。
  3. 主キーとして設定します/ nullではありません。

この回答をコメントで提供した@resnyanskiyにクレジットが付与されます。


2
これは回答としてマークする必要があり、回答は@resnyanskiyに属する必要があります
Eric Wang

最初にpkeyを削除してから、これを実行する必要がありました。 ALTER TABLE <table> DROP CONSTRAINT <pkey_name>;
Josh Robertson、

10

v10でID列を使用するには、

ALTER TABLE test 
ADD COLUMN id { int | bigint | smallint}
GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY PRIMARY KEY;

ID列の説明については、https://blog.2ndquadrant.com/postgresql-10-identity-columns/を参照してください

GENERATED BY DEFAULTとGENERATED ALWAYSの違いについては、https: //www.cybertec-postgresql.com/en/sequences-gains-and-pitfalls/を参照してください

シーケンスの変更については、https://popsql.io/learn-sql/postgresql/how-to-alter-sequence-in-postgresql/を参照してください


この解決策の問題は、テーブルがすでに行が含まれている場合、あなたがエラーを取得することです:SQL Error [23502]: ERROR: column "id" contains null values
isapir

3
@isapir:初期バージョン(10ページと10.1ページ)には、このエラーを引き起こすバグがありました。10.2ページで修正されました。詳細はこちら:dba.stackexchange.com/q/200143/3684
Erwin Brandstetter 2018年

ありがとう@ erwin-brandstetter
isapir

1年後、私はこの回答を再び見つけました。バグは明らかに修正され、賛成投票されました;)
isapir

2

私もそのようなものを探していたので、ここに着陸しました。私の場合、多くの列を持つステージングテーブルのセットから1つのテーブルにデータをコピーすると同時に、ターゲットテーブルに行IDを割り当てていました。ここに私が使用した上記のアプローチの変形があります。ターゲットテーブルの最後にシリアル列を追加しました。そうすれば、Insertステートメントにプレースホルダーを配置する必要がなくなります。次に、ターゲットテーブルへの単純な選択*により、この列に自動入力されます。以下は、PostgreSQL 9.6.4で使用した2つのSQLステートメントです。

ALTER TABLE target ADD COLUMN some_column SERIAL;
INSERT INTO target SELECT * from source;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.