Как установить скользящий windows кадр в диапазоне МЕЖДУ 1 СЛЕДУЮЩИМ И НЕОГРАНИЧЕННЫМ Следование в снежинке - PullRequest
2 голосов
/ 27 мая 2020

Мне нужно преобразовать oracle sql в снежинку sql.

В oracle, у меня это:

last_value(my_table.my_col) 
Over(Partition BY 
my_table.my_col2,
my_table.my_col3
Order By my_table.my_col4 
range BETWEEN 1 Following AND UNBOUNDED Following)

В снежинке, как написано в документации https://docs.snowflake.com/en/user-guide/functions-window-using.html https://docs.snowflake.com/en/sql-reference/functions-analytic.html

Для скользящей рамки диапазон не поддерживается, и я должен использовать строки

Поэтому я должен использовать это :

slidingFrame ::=
{
   ROWS BETWEEN <N> { PRECEDING | FOLLOWING } AND <N> { PRECEDING | FOLLOWING }
 | ROWS BETWEEN UNBOUNDED PRECEDING AND <N> { PRECEDING | FOLLOWING }
 | ROWS BETWEEN <N> { PRECEDING | FOLLOWING } AND UNBOUNDED FOLLOWING
}

Так что я должен использовать это

last_value(my_table.my_col) 
Over(Partition BY 
my_table.my_col2,
my_table.my_col3
Order By my_table.my_col4 
rows BETWEEN 1 Following AND UNBOUNDED Following)

Но выдает ошибку: «Недопустимая оконная рамка»

Примечание:

Я могу сделать

last_value(my_table.my_col) 
Over(Partition BY 
my_table.my_col2,
my_table.my_col3
Order By my_table.my_col4 
rows BETWEEN CURRENT row AND UNBOUNDED Following)

и

last_value(my_table.my_col) 
Over(Partition BY 
my_table.my_col2,
my_table.my_col3
Order By my_table.my_col4 
rows BETWEEN 1 PRECEDING AND UNBOUNDED Following)

без ошибок

Но мне нужен 1 following, чтобы получить тот же результат.

Сделайте Вы хоть представляете, что здесь происходит?

Спасибо

1 Ответ

2 голосов
/ 27 мая 2020

Вы не игнорируете значения NULL, поэтому ваш исходный код для меня выглядит как lead():

lead(my_table.my_col) over (partition by my_table.my_col2, my_table.my_col3
                            order by my_table.my_col4
                           )

Рамка окна не требуется. Это должно работать в обеих базах данных.

EDIT:

@ dnoeth правильно. Это сложная формулировка. Похоже, что logi c помещает последнее значение столбца для всех строк, которые не разделяют окончательное значение. Это кажется странным, но эквивалентно этой формулировке:

first_value(my_table.my_col) over (partition by my_table.my_col2, my_table.my_col3
                                   order by my_table.my_col4 desc
                                  )

Разница в том, что это всегда выбирает последнее значение в столбце. Указанный код возвращает NULL для самого последнего значения. Итак, может потребоваться case:

(case when rank() over (partition by my_table.my_col2, my_table.my_col3
                        order by my_table.my_col4 desc)  > 1 
      then first_value(my_table.my_col) over (partition by my_table.my_col2, my_table.my_col3
                                              order by my_table.my_col4 desc
                                  )
 end)

Здесь - скрипт db <>, использующий Postgres, который принимает оба запроса.

...