#sql #data-science #etl #snowflake-cloud-data-platform #data-analysis
#sql #наука о данных #etl #snowflake-облачная платформа данных #анализ данных
Вопрос:
У меня есть таблица для разных пользователей в snowflake. Мне нужно обновить столбец значений, если есть значение ‘Z’. Z будет заменен ближайшим значением, отличным от Z, от этого пользователя.
Оригинальная таблица:
| User | Order | Value |
| ---- | ------| ----- |
| A | 1 | X |
| A | 2 | Y |
| A | 3 | Z |
| A | 4 | Z |
| A | 5 | W |
| A | 6 | Z |
| B | 1 | Y |
| B | 2 | Z |
| B | 3 | Z |
Целевая таблица:
| User | Order | Value |
| ---- | ------| ----- |
| A | 1 | X |
| A | 2 | Y |
| A | 3 | Y |
| A | 4 | Y |
| A | 5 | W |
| A | 6 | W |
| B | 1 | Y |
| B | 2 | Y |
| B | 3 | Y |
Я написал рекурсивный запрос на обновление. Но исходная таблица содержит миллионы строк. Это потребовало бы очень большого количества рекурсии, что недопустимо в Snowflake. Есть ли какой-либо другой способ, которым я мог бы достичь своей цели? Я думаю о функции window, но не имею представления о том, как ее реализовать.
Ответ №1:
Вы можете использовать lag(ignore nulls)
, чтобы получить предыдущее значение, которое вы хотите. Тогда вы можете использовать join
:
update original o
set value = prev_value
from (select o.*,
lag(case when value <> 'Z' then value end ignore nulls) over (partition by user order by order) as prev_value
from original o
) o2
where o.value = 'Z' and
o2.user = o.user and
o2.order = o.user