Redshift更新最小日期(加入)

时间:2019-05-08 02:43:09

标签: sql amazon-web-services amazon-redshift

我想更新fact表并将init_date字段设置为等于stagingsk_c_id, sk_p_id and lot fields匹配的staging表中最早的日期fact中要更新的行。

companyproduct表也必须被连接

示例对于批次88,发现以下开始日期:该批次中所有序列号中的3月7日,3月8日,3月9日和3月10日。我们想在sk_c_id, sk_p_id, lot

的事实表中将3月7日填充为init_date
company table
+---------+-------+
| sk_c_id | c_id  |
+---------+-------+
| 1       | q23t  |
| 2       | t66y  |
| 3       | yu76  |
+---------+-------+

product table
+---------+-------+
| sk_p_id | p_id  |
+---------+-------+
| 1       | 1123  |
| 2       | 4765  |
| 3       | 7784  |
| 4       | 9088  |
| 5       | 1007  |
+---------+-------+

staging table
+----+---------+---------+-----+-----+-----------+
| id | c_id    | p_id    | lot | xyz | startdate |..
+----+---------+---------+-----+-----+-----------+
| 1  | q23t    |  1123   | 88  | ..  | 2019-03-07|..
| 2  | q23t    |  1123   | 88  | ..  | 2019-03-08|..
| 3  | q23t    |  1123   | 88  | ..  | 2019-03-09|..
| 4  | yu76    |  9088   | 66  | ..  | 2019-02-08|
| 5  | t66y    |  7784   | 88  | ..  | 2019-03-08|
| 6  | t66y    |  7784   | 66  | ..  | 2019-03-18|
| 7  | q23t    |  1007   | 66  | ..  | 2018-08-08|..
| 8  | q23t    |  1123   | 88  | ..  | 2019-03-10|..
+----+---------+---------+-----+-----+-----------+

fact table
+----+---------+---------+-----+-----------+----------+-----+
| id | sk_c_id | sk_p_id | lot | start_date|init_date | xyz |..
+----+---------+---------+-----+-----------+----------+-----+
| 1  | 1       |    1    | 88  | 2019-03-17|2019-03-08| ..  |..
| 2  | 1       |    1    | 88  | 2019-03-08|2019-03-08| ..  |..
| 3  | 1       |    1    | 88  | 2019-03-09|2019-03-08| ..  |..
| 4  | 3       |    4    | 66  | 2019-02-08|2019-02-08| ..  |
| 5  | 2       |    3    | 88  | 2019-03-08|2019-03-08| ..  |
| 6  | 3       |    3    | 66  | 2019-03-18|2019-02-08| ..  |
| 7  | 1       |    5    | 66  | 2018-08-08|2018-08-08| ..  |..
+----+---------+---------+-----+-----------+----------+-----+


这是我到目前为止所拥有的

UPDATE fact
SET init_date = (SELECT initdate FROM (
select s.sk_company_id, s.sk_product_id, min(g.startdate) initdate
from fact f, staging g
GROUP BY f.sk_company_id, f.sk_product_id, f.lot
) st 
join dim_md_company c on c.sk_company_id = st.sk_company_id
join staging_product p on p.sk_product_id = st.sk_product_id

但是这似乎不起作用。我已经解决了一些关于stackoverflow的问题,但似乎对我没有任何帮助。 正确的查询是什么?

1 个答案:

答案 0 :(得分:0)

因此,目标是更新fact表并将init_date字段设置为等于登台表中最早的startdate,其中sk_c_id,{{1暂存中的}}和sk_p_id字段与lot中正在更新的行匹配。

让我们从获取给定公司,产品和批次的最低fact开始吧

startdate

要对此进行测试,我们可以将其连接到SELECT sk_c_id, sk_p_id, lot, MIN(startdate) as min_start_date FROM staging JOIN company c USING (c_id) JOIN product p USING (p_id) GROUP BY sk_c_id, sk_p_id, lot 表中以查看最终输出是什么样的:

fact

结果显示为:

SELECT
  f.*,
  s.min_start_date
FROM fact f
JOIN (SELECT sk_c_id, sk_p_id, lot, MIN(startdate) as min_start_date
      FROM staging
      JOIN company c USING (c_id)
      JOIN product p USING (p_id)
      GROUP BY sk_c_id, sk_p_id, lot
     ) s USING (sk_c_id, sk_p_id, lot)

请注意,这些结果显示3 1 1 88 2019-03-09 2019-03-07 2 1 1 88 2019-03-08 2019-03-07 1 1 1 88 2019-03-17 2019-03-07 7 1 5 66 2018-08-08 2018-08-08 5 2 3 88 2019-03-08 2019-03-08 4 3 4 66 2019-02-08 2019-02-08 2019-03-07的最小startdate。这与您的1, 1, 88的示例输出不同,但是我认为您的示例日期实际上是错误的。

然后将其转换为2019-03-08语句即可。

UPDATE

请注意,在一行上使用UPDATE fact SET init_date = min_start_date FROM (SELECT sk_c_id, sk_p_id, lot, MIN(startdate) as min_start_date FROM staging JOIN company c USING (c_id) JOIN product p USING (p_id) GROUP BY sk_c_id, sk_p_id, lot ) s WHERE fact.sk_c_id = s.sk_c_id AND fact.sk_p_id = s.sk_p_id AND fact.lot = s.lot 时,Amazon Redshift将现有行标记为 Deleted ,并在存储区域的末尾为每一列创建一个新行。因此,存储变得零散且混乱。

因此,建议在执行UPDATE之后在表上执行VACCUUM

在执行UPDATE之前进行备份(快照)也是一个好主意,以防数据被意外覆盖。