Как сбросить последовательность в postgres и заполнить столбец id новыми данными? - PullRequest
90 голосов
/ 13 января 2011

У меня есть таблица с более чем миллионом строк.Мне нужно сбросить последовательность и переназначить столбец id с новыми значениями (1, 2, 3, 4 ... и т. Д.).Есть ли простой способ сделать это?

Ответы [ 13 ]

157 голосов
/ 13 января 2011

Если вы не хотите сохранять порядок идентификаторов, тогда вы можете

ALTER SEQUENCE seq RESTART WITH 1;
UPDATE t SET idcolumn=nextval('seq');

Я сомневаюсь, что есть простой способ сделать это в порядке вашего выбора без воссоздания всей таблицы.

35 голосов
/ 13 января 2011

Сброс последовательности:

SELECT setval('sequence_name', 0);

Обновление текущих записей:

UPDATE foo SET id = DEFAULT;
30 голосов
/ 11 декабря 2012

В PostgreSQL 8.4 или новее нет необходимости указывать WITH 1. Будет использовано начальное значение, записанное CREATE SEQUENCE или последнее установленное ALTER SEQUENCE START WITH (скорее всего, это будет 1).

Сброс последовательности:

ALTER SEQUENCE seq RESTART;

Затем обновите столбец идентификатора таблицы:

UPDATE foo SET id = DEFAULT;

Источник: Документы PostgreSQL

16 голосов
/ 13 июля 2012

Оба предоставленных решения не работают для меня;

> SELECT setval('seq', 0);
ERROR:  setval: value 0 is out of bounds for sequence "seq" (1..9223372036854775807)

setval('seq', 1) начинает нумерацию с 2, а ALTER SEQUENCE seq START 1 также начинает нумерацию с 2, поскольку seq.is_called имеет значение true (Postgresверсия 9.0.4)

Решение, которое сработало для меня:

> ALTER SEQUENCE seq RESTART WITH 1;
> UPDATE foo SET id = DEFAULT;
12 голосов
/ 23 августа 2016

Просто для упрощения и уточнения правильного использования ALTER SEQUENCE и SELECT setval для сброса последовательности:

ALTER SEQUENCE sequence_name RESTART WITH 1;

эквивалентно

SELECT setval('sequence_name', 1, FALSE);

Любое из операторов может использоваться для сброса последовательности, и вы можете получить следующее значение, используя nextval ('sequence_name'), как указано здесь также:

nextval('sequence_name')
8 голосов
/ 07 декабря 2017

Лучший способ сбросить последовательность для запуска с номера 1 - выполнить следующее:

ALTER SEQUENCE <tablename>_<id>_seq RESTART WITH 1

Так, например, для таблицы пользователей это будет:

ALTER SEQUENCE users_id_seq RESTART WITH 1
4 голосов
/ 21 мая 2014

К вашему сведению: если вам нужно указать новое начальное значение между диапазонами идентификаторов (например, 256 - 10000000):

SELECT setval('"Sequence_Name"', 
       (SELECT coalesce(MAX("ID"),255) 
           FROM "Table_Name" 
           WHERE "ID" < 10000000 and "ID" >= 256)+1
       ); 
3 голосов
/ 20 апреля 2015

Для сохранения порядка строк:

UPDATE thetable SET rowid=col_serial FROM 
(SELECT rowid, row_number() OVER ( ORDER BY lngid) AS col_serial FROM thetable ORDER BY lngid) AS t1 
WHERE thetable.rowid=t1.rowid;
1 голос
/ 22 августа 2017

В моем случае я достиг этого с помощью:

ALTER SEQUENCE table_tabl_id_seq RESTART WITH 6;

Где моя таблица называется table

1 голос
/ 20 июня 2016

Просто сброс последовательности и обновление всех строк может привести к ошибкам дублирующегося идентификатора. Во многих случаях вы должны обновить все строки дважды. Сначала с более высокими идентификаторами, чтобы избежать дубликатов, затем с идентификаторами, которые вы действительно хотите.

Пожалуйста, избегайте добавления фиксированной суммы ко всем идентификаторам (как рекомендуется в других комментариях). Что произойдет, если у вас будет больше строк, чем эта фиксированная сумма? Предполагая, что следующее значение последовательности больше всех идентификаторов существующих строк (вы просто хотите заполнить пробелы), я бы сделал это следующим образом:

UPDATE table SET id = DEFAULT;
ALTER SEQUENCE seq RESTART;
UPDATE table SET id = DEFAULT;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...