Redshift обновление минимальной даты с присоединением - PullRequest
0 голосов
/ 08 мая 2019

Я хочу обновить таблицу fact и установить поле init_date равным самой ранней дате в таблице staging, где sk_c_id, sk_p_id and lot fields в staging соответствует строке, обновляемой в fact. *Таблицы 1007 *

company и product также должны быть объединены

Пример Для лота 88 были найдены следующие начальные даты: 7 марта, 8 марта, 9 марта, 10 марта средивсе серийные номера как часть этого лота.Мы хотим заполнить 7 марта как таблицу фактов init_date для 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, но мне кажется, что ничего не работает.Какой будет правильный запрос для него?

1 Ответ

0 голосов
/ 09 мая 2019

Таким образом, цель состоит в том, чтобы обновить таблицу fact и установить поле init_date равным самым ранним startdate в промежуточной таблице, где поля sk_c_id, 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

Обратите внимание, что при использовании UPDATE в строке Amazon Redshift помечает существующую строку как Удалено и создает новую строку в конце области хранения для каждого столбца. Таким образом, хранилище становится фрагментированным и выходит из строя.

Поэтому рекомендуется выполнить VACCUUM на столе после выполнения UPDATE.

Также было бы неплохо сделать резервную копию (снимок) перед выполнением UPDATE на случай непреднамеренной перезаписи данных.

...