#snowflake-cloud-data-platform
#снежинка-облачная платформа для обработки данных
Вопрос:
У меня есть такая таблица в Snowflake, где у меня есть столбец «класс», где все строки с уровнем 1 имеют значение. Я хотел бы иметь новый столбец «WANTED_OUTPUT», где значение из класса заполняется до тех пор, пока не появится новое значение, а затем заполняется этим значением.
Я просматривал функции first_value и last_value, но я что-то пропустил, что может «сгруппировать» все строки с уровня 1 до следующего уровня 1 вместе, прежде чем я смогу использовать first_value и раздел поверх этого.
Есть предложения?
---- ------- ------- ------- ---------------
| id | col_c | level | class | WANTED_OUTPUT |
---- ------- ------- ------- ---------------
| a | q1 | 1 | c99 | c99 |
---- ------- ------- ------- ---------------
| a | w2 | 2 | NULL | c99 |
---- ------- ------- ------- ---------------
| a | g6 | 2 | NULL | c99 |
---- ------- ------- ------- ---------------
| a | j5 | 3 | NULL | c99 |
---- ------- ------- ------- ---------------
| a | x8 | 1 | c3 | c3 |
---- ------- ------- ------- ---------------
| a | x9 | 2 | NULL | c3 |
---- ------- ------- ------- ---------------
| a | h5 | 1 | c67 | c67 |
---- ------- ------- ------- ---------------
Ответ №1:
Использование FIRST/LAST_VALUE
:
SELECT *,
FIRST_VALUE(class) IGNORE NULLS OVER (PARTITION BY id ORDER BY level) AS wanted
FROM tab;
Таблицы представляют собой неупорядоченные наборы по дизайну, поэтому требуется стабильная сортировка. Уровень может быть недостаточным в зависимости от предоставленных входных данных.
Предложение: было бы предпочтительнее добавить явную временную метку или столбец seq id для обеспечения стабильной сортировки столбца.
SELECT tab.*,
LAST_VALUE(class) IGNORE NULLS OVER (PARTITION BY id
ORDER BY rn
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS wanted
FROM tab;
Комментарии:
1. В моем небольшом примере в строках 1-4 показано, как одна и та же группа, основанная на моем столбце ID и уровне, и строка 5-6 — это другая группа с тем же идентификатором, но новый «уровень 1», а строка 7 — это собственная группа, я думаю, что это следует перевести в столбец «помощник» для разделения. Но я не знаю, как это сделать.
2. @jvels Вы могли бы создать какое-то ненадежное поведение, но без стабильной сортировки это невозможно.
WITH cte AS (SELECT *, ROW_NUMBER() OVER(PARTITION BY id ORDER BY id) AS rn FROM tab) SELECT *, FIRST_VALUE(class) IGNORE NULLS OVER (PARTITION BY id ORDER BY rn) AS wanted FROM cte
; — здесь есть неявное предположение, что при создании rn данные считываются так, как они были вставлены. Я предлагаю добавить явную временную метку или столбец идентификатора, чтобы обеспечить стабильную сортировку столбца.