Снежинка заполняет нулевые значения

#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;
 

db<>демонстрация скрипки

Комментарии:

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 данные считываются так, как они были вставлены. Я предлагаю добавить явную временную метку или столбец идентификатора, чтобы обеспечить стабильную сортировку столбца.