我想更新fact
表并将init_date
字段设置为等于staging
中sk_c_id, sk_p_id and lot fields
匹配的staging
表中最早的日期fact
中要更新的行。
company
和product
表也必须被连接
示例对于批次88,发现以下开始日期:该批次中所有序列号中的3月7日,3月8日,3月9日和3月10日。我们想在sk_c_id, sk_p_id, lot
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的问题,但似乎对我没有任何帮助。 正确的查询是什么?
答案 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
之前进行备份(快照)也是一个好主意,以防数据被意外覆盖。