批量更新Redshift中的现有行

时间:2014-03-20 19:22:20

标签: sql postgresql amazon-redshift

这似乎应该很容易,但事实并非如此。我正在将查询从MySQL迁移到Redshift:

INSERT INTO table
(...)
VALUES
(...)
ON DUPLICATE KEY UPDATE
  value = MIN(value, VALUES(value))

对于我们正在插入的主键,这些主键只是已插入表中。对于已在表中的主键,我们根据取决于行中现有值和新值的条件更新行的值。

http://docs.aws.amazon.com/redshift/latest/dg/merge-replacing-existing-rows.html不起作用,因为在我的情况下filter_expression取决于表中的当前条目。我正在创建一个临时表,使用COPY语句插入其中,并试图找出合并登台表和真实表的最佳方法。

3 个答案:

答案 0 :(得分:10)

我现在必须为一个项目做这件事。我使用的方法包括3个步骤:

<强> 1

运行更新以解决已更改的字段(我更新字段是否已更改,但您当然可以限定该字段):

update table1 set col1=s.col1, col2=s.col2,...
from table1 t
 join stagetable s on s.primkey=t.primkey;

<强> 2

运行一个解决新记录的插入内容:

insert into table1
select s.* 
from stagetable s 
 left outer join table1 t on s.primkey=t.primkey
where t.primkey is null;

第3

将源中的行不再标记为非活动状态(我们的报告工具使用过滤非活动记录的视图):

update table1 
set is_active_flag='N', last_updated=sysdate
from table1 t
 left outer join stagetable s on s.primkey=t.primkey
where s.primkey is null;

答案 1 :(得分:0)

是否可以创建临时表。在redshift中最好删除并插入记录。 查看此文档

http://docs.aws.amazon.com/redshift/latest/dg/merge-replacing-existing-rows.html

答案 2 :(得分:0)

这是Redshift的全面工作方法。

<强>假设:

A. S3 gunzip 格式提供的'|'分隔列,可能有一些垃圾数据,请参阅 maxerror

B.Sales事实与两个维度表保持简单(TIME和SKU(SKU可能有许多组和类别))。)

C.你有这样的销售表。

CREATE TABLE sales (
 sku_id int encode zstd,
 date_id int encode zstd,
quantity numeric(10,2) encode delta32k,
);

1)创建临时表,该表应与app / apps使用的在线表类似。

CREATE TABLE stg_sales_onetime (
 sku_number varchar(255) encode zstd,
 time varchar(255) encode zstd,
 qty_str varchar(20) encode zstd,
 quantity numeric(10,2) encode delta32k,
 sku_id int encode zstd,
 date_id int encode zstd
);

2)从S3复制数据(这可以使用SSH完成)。

copy stg_sales_onetime (sku_number,time,qty_str) from 
  's3://<buecket_name>/<full_file_path>' CREDENTIALS 'aws_access_key_id=<your_key>;aws_secret_access_key=<your_secret>' delimiter '|' ignoreheader 1 maxerror as 1000 gzip;

3)此步骤是可选的,如果您没有良好的格式化数据,如果需要,这是您的转换步骤(将String(12.555654)数量转换为Number(12.56))

update  stg_sales_onetime set quantity=convert(decimal(10,2),qty_str);

4)从维度表中填充正确的ID。

update  stg_sales_onetime set sku_id=<your_sku_demesion_table>.sku_id  from <your_sku_demesion_table> where stg_sales_onetime.sku_number=<your_sku_demesion_table>.sku_number;
update  stg_sales_onetime set time_id=<your_time_demesion_table>.time_id  from <your_time_demesion_table> where stg_sales_onetime.time=<your_time_demesion_table>.time;

5)最后,您可以获得从登台到在线销售表的数据。

insert into sales(sku_id,time_id,quantity)  select sku_id,time_id,quantity from stg_sales_onetime;