我有两张桌子。其中一个是临时表,我从中复制大型CSV文件中的数据。之后,我使用临时表更新我的另一个表(请参阅此答案:Copy a few of the columns of a csv file into a table)。
当我使用(更新的)CSV文件(来自bash中的grep的数据,每次更新增加行数)再次更新我的临时表时,我想删除不受更新影响的行。我可以让临时表小于包含所有数据的临时表。
首先:最好是删除临时表中的所有数据并用完整的更新CSV数据填充它,然后更新/插入另一个表。 第二:或者首先更新临时表?
所以这是表的大小问题。我说的是500k行(带几何列)。
一个例子:
table
1, NULL
2, NULL
temp table
1, hello
2, good morning
CSV
1, hello there
2, good morning
3, good evening
temp table
1, hello there
2, good morning
3, good evening
OR
temp table
1, hello there
3, good evening
所以我的问题是如何使用CSV文件更新表,插入新行,更新旧行并删除不受更新影响的行。
答案 0 :(得分:1)
所以我的问题是如何使用CSV文件更新表,插入新行,更新旧行并删除不受更新影响的行。
我看到两种可能的解决方案:
数据应用了一系列更新/删除/插入语句,如下所示:
-- get rid of deleted rows
delete from the_table
where not exists (select 1
from temp_table tt
where tt.id = the_table.id);
-- update changed data
update the_table
set ..
from temp_table src
where src.id = the_table.id;
-- insert new rows
insert into the_table
select ..
from temp_table src
where not exists (select 1
from the_table t2
where t2.id = src.id);
如果其他源写入目标表并且您不想覆盖它,则这是必需的方法。也许你甚至不想删除“缺失”行。或者只更新列的子集。
如果你从不修改目标表中的数据并且你没有引用该表的外键,我会对真实表进行刷新和填充:
truncate the_table;
copy the_table from '/path/to/data.csv' ...;
如果您在单个事务中运行truncate
和copy
,则复制性能将得到改善,因为它可以最大限度地减少WAL日志记录的数量。
答案 1 :(得分:0)
我对SQL(半年)的经验不多,但是你可能会使用MINUS子句比较你的表吗?使用MINUS可以获得未更新的行吗? 附:我在谈论PL / SQL)