MW211 EXIT

devlog
PostgreSQL/(新)連番を前詰に振り直す
2013年10月19日
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│    SET 列 = (SELECT COUNT(*)                                               │
│                  FROM 表 AS 別表                                           │
│                  WHERE 別表.列 <= 表.列);                                  │
├──────────────────────────────────────┤
│SELECT setval ('AutoNumber用列名', (SELECT COUNT(*) FROM 表), true);        │
└──────────────────────────────────────┘

以下、検証例。

テスト用データを作成する。
┌──────────────────────────────────────┐
│CREATE TABLE "test"                                                         │
│(                                                                           │
│    "id" bigserial NOT NULL,                                                │
│    "no" integer   NOT NULL,                                      ┌─┬─┐│
│    PRIMARY KEY ("id")                                            │id│no││
│);                                                                ├─┼─┤│
├─────────────────────────────────│ 1│ 1│┤
│INSERT INTO "test" ("no") VALUES (1);                             │ 2│ 2││
│INSERT INTO "test" ("no") VALUES (2);                             │ 3│ 3││
│INSERT INTO "test" ("no") VALUES (3);                             │ 4│ 4││
│INSERT INTO "test" ("no") VALUES (4);                             │ 5│ 5││
│INSERT INTO "test" ("no") VALUES (5);                             │ 6│ 6││
│INSERT INTO "test" ("no") VALUES (6);                             │ 7│ 7││
│INSERT INTO "test" ("no") VALUES (7);                             │ 8│ 8││
│INSERT INTO "test" ("no") VALUES (8);                             └─┴─┘│
└──────────────────────────────────────┘

欠番をつくる。
┌─────────────────────────────────┌─┬─┐┐
│DELETE FROM "test" WHERE "id" = 1;                                │id│no││
│DELETE FROM "test" WHERE "id" = 3;                                ├─┼─┤│
│DELETE FROM "test" WHERE "id" = 5;                                │ 2│ 2││
│DELETE FROM "test" WHERE "id" = 7;                                │ 4│ 4││
└─────────────────────────────────│ 6│ 6│┘
                                                                    │ 8│ 8│
                                                                    └─┴─┘

前詰に更新し直す。
┌─────────────────────────────────┌─┬─┐┐
│UPDATE "test"                                                     │id│no││
│    SET "id" = (SELECT COUNT(*)                                   ├─┼─┤│
│                         FROM "test" AS "as_test"                 │ 1│ 2││
│                         WHERE "as_test"."id" <= "test"."id");    │ 2│ 4││
└─────────────────────────────────│ 3│ 6│┘
                                                                    │ 4│ 8│
                                                                    └─┴─┘

最終連番が「8」のままなので、「4」に戻す。
┌──────────────────────────────────────┐
│SELECT setval ('test_id_seq', (SELECT COUNT(*) FROM "test"), true);         │
└──────────────────────────────────────┘

試しに新たなデータを追加すると、適切に末尾に追加されることが確認できる。
┌─────────────────────────────────┌─┬─┐┐
│INSERT INTO "test" ("no") VALUES (99);                            │id│no││
└─────────────────────────────────├─┼─┤┘
                                                                    │ 1│ 2│
                                                                    │ 2│ 4│
                                                                    │ 3│ 6│
                                                                    │ 4│ 8│
                                                                    │ 5│99│
                                                                    └─┴─┘
分類:PostgreSQL