Разница между «ROWS BETWEEN» и «RANGE BETWEEN» в (Presto) оконной функции в предложении «OVER» - PullRequest
2 голосов
/ 19 февраля 2020

Вопросы (tl; dr)

  1. В чем разница между ROWS BETWEEN и RANGE BETWEEN в функциях окна Presto?
    • Являются ли это просто синонимами друг для друга, или есть основные концептуальные различия?
    • Если они просто синонимы, почему ROWS BETWEEN допускает больше опций, чем RANGE BETWEEN?
  2. Существует ли сценарий запроса, в котором можно использовать одинаковые параметры для ROWS BETWEEN и RANGE BETWEEN и получать разные результаты?
    • Если используется только unbounded / current row, есть ли сценарий, в котором вы бы использовали RANGE вместо ROWS (или наоборот)?
  3. Поскольку ROWS имеет больше опций, почему это вообще не упоминается в документации? o_O

Комментарии

Документация presto довольно тиха даже относительно RANGE и не упоминает ROWS. Я не нашел много обсуждений или примеров вокруг оконных функций в Presto. Я начинаю устанавливать кодовую базу Presto, чтобы попытаться понять это. Надеюсь, кто-то может спасти меня от этого, и мы вместе сможем улучшить документацию.

В коде Presto есть анализатор и тестовых случаев для варианта ROWS, но нет упоминания в документации из ROWS.

тестовых случаев Я обнаружил, что с ROWS и RANGE не тестируют ничего различного между двумя синтаксисами.

Они почти выглядят как синонимы, но в моем тестировании они ведут себя по-разному и имеют различные допустимые параметры и правила проверки .

Следующее примеры могут быть запущены с starburstdata / presto Docker образом с Presto 0.213-e-0.1. Обычно я запускаю Presto 0.172 через Amazon Athena и почти всегда использую ROWS.

RANGE

RANGE, кажется, ограничен значениями «UNBOUNDED» и «CURRENT ROW». Следующее возвращает ошибку:

range between 1 preceding and 1 following

use tpch.tiny;

select custkey, orderdate,
       array_agg(orderdate) over ( 
           partition by custkey 
           order by orderdate asc 
           range between 1 preceding and 1 following
       ) previous_orders 
from orders where custkey in (419, 320) and orderdate < date('1996-01-01')
order by custkey, orderdate asc;

ОШИБКА: Window frame RANGE PRECEDING is only supported with UNBOUNDED

Синтаксис следующих диапазонов работает нормально (с ожидаемыми отличающимися результатами). Все последующие примеры, основанные на приведенном выше запросе, просто меняют диапазон

range between unbounded preceding and current row

 custkey | orderdate  |                             previous_orders
---------+------------+--------------------------------------------------------------------------
     320 | 1992-07-10 | [1992-07-10]
     320 | 1992-07-30 | [1992-07-10, 1992-07-30]
     320 | 1994-07-08 | [1992-07-10, 1992-07-30, 1994-07-08]
     320 | 1994-08-04 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04]
     320 | 1994-09-18 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18]
     320 | 1994-10-12 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     419 | 1992-03-16 | [1992-03-16]
     419 | 1993-12-29 | [1992-03-16, 1993-12-29]
     419 | 1995-01-30 | [1992-03-16, 1993-12-29, 1995-01-30]

range between current row and unbounded following

 custkey | orderdate  |                             previous_orders
---------+------------+--------------------------------------------------------------------------
     320 | 1992-07-10 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1992-07-30 | [1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1994-07-08 | [1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1994-08-04 | [1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1994-09-18 | [1994-09-18, 1994-10-12]
     320 | 1994-10-12 | [1994-10-12]
     419 | 1992-03-16 | [1992-03-16, 1993-12-29, 1995-01-30]
     419 | 1993-12-29 | [1993-12-29, 1995-01-30]
     419 | 1995-01-30 | [1995-01-30]

диапазон между неограниченным предшествующим и неограниченным следующим

 custkey | orderdate  |                             previous_orders
---------+------------+--------------------------------------------------------------------------
     320 | 1992-07-10 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1992-07-30 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1994-07-08 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1994-08-04 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1994-09-18 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1994-10-12 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04, 1994-09-18, 1994-10-12]
     419 | 1992-03-16 | [1992-03-16, 1993-12-29, 1995-01-30]
     419 | 1993-12-29 | [1992-03-16, 1993-12-29, 1995-01-30]
     419 | 1995-01-30 | [1992-03-16, 1993-12-29, 1995-01-30]

ROWS

Три рабочих примера для RANGE превыше всего работать на ROWS и производить идентичный вывод.

rows between unbounded preceding and current row
rows between current row and unbounded following
rows between unbounded preceding and unbounded following

выходной сигнал пропущен - идентично указанному выше

Однако ROWS обеспечивает гораздо больший контроль, поскольку вы также можете выполнить приведенный выше синтаксис, который не работает с range:

rows between 1 preceding and 1 following

 custkey | orderdate  |           previous_orders
---------+------------+--------------------------------------
     320 | 1992-07-10 | [1992-07-10, 1992-07-30]
     320 | 1992-07-30 | [1992-07-10, 1992-07-30, 1994-07-08]
     320 | 1994-07-08 | [1992-07-30, 1994-07-08, 1994-08-04]
     320 | 1994-08-04 | [1994-07-08, 1994-08-04, 1994-09-18]
     320 | 1994-09-18 | [1994-08-04, 1994-09-18, 1994-10-12]
     320 | 1994-10-12 | [1994-09-18, 1994-10-12]
     419 | 1992-03-16 | [1992-03-16, 1993-12-29]
     419 | 1993-12-29 | [1992-03-16, 1993-12-29, 1995-01-30]
     419 | 1995-01-30 | [1993-12-29, 1995-01-30]

rows between current row and 1 following

 custkey | orderdate  |     previous_orders
---------+------------+--------------------------
     320 | 1992-07-10 | [1992-07-10, 1992-07-30]
     320 | 1992-07-30 | [1992-07-30, 1994-07-08]
     320 | 1994-07-08 | [1994-07-08, 1994-08-04]
     320 | 1994-08-04 | [1994-08-04, 1994-09-18]
     320 | 1994-09-18 | [1994-09-18, 1994-10-12]
     320 | 1994-10-12 | [1994-10-12]
     419 | 1992-03-16 | [1992-03-16, 1993-12-29]
     419 | 1993-12-29 | [1993-12-29, 1995-01-30]
     419 | 1995-01-30 | [1995-01-30]

rows between 5 preceding and 2 preceding

 custkey | orderdate  |                 previous_orders
---------+------------+--------------------------------------------------
     320 | 1992-07-10 | NULL
     320 | 1992-07-30 | NULL
     320 | 1994-07-08 | [1992-07-10]
     320 | 1994-08-04 | [1992-07-10, 1992-07-30]
     320 | 1994-09-18 | [1992-07-10, 1992-07-30, 1994-07-08]
     320 | 1994-10-12 | [1992-07-10, 1992-07-30, 1994-07-08, 1994-08-04]
     419 | 1992-03-16 | NULL
     419 | 1993-12-29 | NULL
     419 | 1995-01-30 | [1992-03-16]
...