postgresql版本将数据从一个表移动到另一个表

时间:2010-06-04 12:27:45

标签: sql postgresql

我想将一些数据从一个表移动到另一个表(可能有不同的模式)。想到的直接解决方案是 -

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中,RULE或存储过程可用于动态删除数据,仅评估条件一次。哪种解决方案更好?还有其他选择吗?

4 个答案:

答案 0 :(得分:39)

[展开dvv's answer]

您可以按如下方式移动到现有表格。对于不匹配的架构,您应该指定列。

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;

答案 1 :(得分:7)

如果条件太复杂而你不想执行两次(BTW听起来不太可能,但无论如何),原始表上的ALTER TABLE ... ADD COLUMN可能会添加一个布尔字段,并在表格上运行UPDATE以将该字段设置为true WHERE <condition>。然后,您的INSERTDELETE命令只需在此列中查看其WHERE子句。

不要忘记之后从源表和目标表中删除该列!

嗯,更不干扰的是创建一个新的临时表,其唯一目的是包含要包含的记录的PK。首先INSERT到此表以“定义”要操作的行集,然后使用此表连接表复制INSERTDELETE。由于表PK被编入索引,因此这些连接将很快。


<强> [编辑] 斯科特贝利在评论中的建议显然是正确的方法,希望我自己想到它!假设所有原始表的PK字段都将出现在目标表中,不需要临时表 - 只需使用复杂的WHERE条件插入目标,然后{{ 1}}从原始表加入此表。现在建议一个单独的桌子我觉得很蠢! :)

答案 2 :(得分:7)

您可以使用Postgres 9.1中的SINGLE查询移动数据 见http://www.postgresql.org/docs/9.1/static/queries-with.html “在WITH中修改数据的数据”部分

答案 3 :(得分:0)

您可以将表数据转储到文件中,然后使用COPY将其插入另一个表中 通常COPYINSERT快。