переместить данные из одной таблицы в другую, выпуск postgresql - PullRequest
12 голосов
/ 04 июня 2010

Я хотел бы переместить некоторые данные из одной таблицы в другую (возможно, с другой схемой). Простое решение, которое приходит в голову, -

start a transaction with serializable isolation level;
INSERT INTO dest_table SELECT data FROM orig_table,other-tables WHERE <condition>;
DELETE FROM orig_table USING other-tables WHERE <condition>;
COMMIT;

А что, если объем данных достаточно велик, а <condition> требует больших затрат? В PostgreSQL ПРАВИЛО или хранимая процедура могут использоваться для удаления данных на лету, оценивая состояние только один раз. Какое решение лучше? Есть ли другие варианты?

Ответы [ 4 ]

41 голосов
/ 11 февраля 2014

[Расширение ответ dvv ]

Вы можете перейти к существующей таблице следующим образом. Для несоответствующей схемы вы должны указать столбцы.

WITH moved_rows AS (
    DELETE FROM <original_table> a
    USING <other_table> b
    WHERE <condition>
    RETURNING a.* -- or specify columns
)
INSERT INTO <existing_table> --specify columns if necessary
SELECT [DISTINCT] * FROM moved_rows;

Но вы хотите переместить данные в новую таблицу (не существующую), внешний синтаксис другой:

CREATE TABLE <new_table> AS
WITH moved_rows AS (
    DELETE FROM <original_table> a
    USING <other_table> b
    WHERE <condition>
    RETURNING a.* -- or specify columns
)
SELECT [DISTINCT] * FROM moved_rows;
7 голосов
/ 04 июня 2010

Если условие настолько сложное, что вы не хотите выполнять его дважды (что, кстати, звучит маловероятно для меня, но в любом случае), одна из возможностей будет ALTER TABLE ... ADD COLUMN на исходной таблице, чтобы добавить логическое поле, и запустите UPDATE для таблицы, чтобы установить для этого поля значение true WHERE <condition>. Тогда ваши команды INSERT и DELETE могут просто проверить этот столбец на наличие предложений WHERE.

Не забудьте впоследствии удалить столбец из исходной и целевой таблиц!

Хм, еще менее навязчиво было бы создать новую временную таблицу, единственная цель которой - содержать PK записей, которые вы хотите включить. Сначала INSERT к этой таблице, чтобы «определить» набор строк для работы, а затем присоединиться к этой таблице для копирования таблиц INSERT и DELETE. Эти объединения будут быстрыми, так как таблицы PK индексируются.


[EDIT] Предложение Скотта Бэйли в комментариях, очевидно, является правильным способом сделать это, если бы я думал об этом сам! Предполагая, что все поля PK исходной таблицы будут присутствовать в таблице назначения, нет необходимости во временной таблице - просто используйте сложные условия WHERE для вставки в место назначения, затем DELETE из оригинальная таблица, присоединившись к этой таблице. Я чувствую себя глупо, предлагая отдельную таблицу сейчас! :)

7 голосов
/ 11 ноября 2011

Вы можете перемещать данные, используя ОДИН запрос в Postgres 9.1. Смотри http://www.postgresql.org/docs/9.1/static/queries-with.html Раздел «Изменения данных в СО»

0 голосов
/ 04 июня 2010

Вы можете вывести данные таблицы в файл, а затем вставить их в другую таблицу, используя COPY Обычно COPY быстрее INSERT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...