2016-02-19 4 views
4

Мне нужно выбрать несколько столбцов как часть инструкции LEAD. Это выглядит, как это будет действительно неэффективно, утроить число видов и разделов требуется ->Повторное использование раздела функций окна BigQuery

SELECT 
    field, 
    field2, 
    field3, 
    LEAD(field, 1) OVER (PARTITION BY field ORDER BY field ASC) AS nextField, 
    LEAD(field2, 1) OVER (PARTITION BY field ORDER BY field ASC) AS nextField2, 
    LEAD(field3, 1) OVER (PARTITION BY field ORDER BY field ASC) AS nextField3, 
FROM dataset.table 
  • Есть ли лучший способ сделать это?
  • Оптимизирует ли BigQuery для этого во время выполнения запроса, чтобы сделать его эффективным?
+0

Возможно объединить поля в одно поле, а затем сделать вывод, а затем просто разделить эту строку. – andrewm4894

ответ

4

Пара точек добавить ответ Михаила:

  1. Да, BigQuery оптимизирует его - если оконный кадр одинаков, он будет настроен только один раз, и над ним будет работать несколько функций.

  2. Вы правы, что это утомительно писать тот же кадр, снова и снова, поэтому мы работали над улучшением BigQuery SQL диалект, чтобы сделать его более совместим со стандартом, и в ближайшем будущем * вы будете иметь возможность писать


SELECT 
    field, 
    field2, 
    field3, 
    LEAD(field, 1) OVER w1 AS nextField, 
    LEAD(field2, 1) OVER w1 AS nextField2, 
    LEAD(field3, 1) OVER w1 AS nextField3, 
FROM dataset.table 
WINDOW w1 AS (PARTITION BY field ORDER BY field ASC) 

* не могу дать вам точную дату, но это внутреннее тестирование прямо сейчас, так не должно быть слишком длинным.

+0

Отлично, спасибо вам обоим! –

1

Window Functions уже достаточно изящный, чтобы выразить в SQL свою бизнес-логику. Хотя кажется, что вам нужно повторить часть PARTITION BY ... ORDER BY ... для каждого соответствующего поля вывода инструкции SELECT, я лично не думаю, что это большая цена за власть, которую предоставляют нам функции окна.
Кстати, вы не ограничены использованием только одного PARTITION BY для всех полей вывода - вы можете использовать любой раздел, который вам нужен для каждого. То же самое для ORDER BY

Оптимизирует ли BigQuery для этого во время выполнения запроса, чтобы сделать его эффективным?

После выполнения запроса вы можете проверить Query Plan Explanation.
Это ясно показывает, что BigQuery повторно использует разделы независимо от того, сколько функций окна вы используете. И выглядит, если у вас есть несколько разных разделов, которые они каскадируют. (это также ясно, если вы видите план запроса)

Есть ли лучший способ сделать это?

Вы можете имитировать функцию окна с разделением - несколькими способами. Ни один из них, похоже, не работает и/или читается/управляется так же хорошо, как при использовании оконных функций.

Например, ниже логика будет давать тот же результат (только логика высокого уровня здесь).
Высылаю ROW_NUMBER() OVER(PARTITION BY ... ORDER BY ...) as POS в исходное данные/таблицу.
Чем вы присоединяетесь к нему с помощью ON a.partition = b.partition AND a.POS = a. (POS + 1) < - это просто логика, а не реализация
Итак, теперь у вас будут все текущие значения в таблице с псевдонимом а и все последующие значения в таблице псевдоним б

Как я уже упоминал выше производит точно такой же результат, как и функции окна, но код выглядит гораздо более уродливые и исполнение показывает гораздо более дорогой

+0

Отлично, спасибо! –

Смежные вопросы