Bigquery - Оконная агрегация - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь использовать оконную функцию для каждого дня продажи пометок, чтобы получить сумму за последние 365 дней по количеству пометок.Если бы это продавалось каждый день, тогда я мог бы использовать ROWS, PRECEDING и т. Д.

ORDER BY
      CalendarFullDate ROWS BETWEEN 364 PRECEDING AND CURRENT ROW

Но в этом случае даты распределяются неравномерно, так как многие дни не продаются (т.е. я не могу просто вернуться назад 364строки и предполагают распродажу каждый день).

Итак, с тестом / образцом, приведенным ниже, возможно ли использовать оконное управление и какой-то тип условия where, чтобы я суммировал только самое большее 364 дня?

WITH samples AS (
  SELECT "1" AS SKU, DATE("2018-10-27") AS CalendarFullDate, 86.0 AS DailySalesQty UNION ALL (
  SELECT "1" AS SKU, DATE("2018-10-20"), 84.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-09-29"), 88.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-09-14"), 42.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-09-01"), 21.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-05-05"), 25.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-04-28"), 97.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-03-31"), 244.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-03-24"), 68.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-02-23"), 52.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-02-10"), 48.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-01-21"), 243.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-01-18"), 2.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2018-01-06"), 190.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-12-26"), 310.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-12-09"), 240.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-11-03"), 30.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-10-21"), 164.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-09-30"), 44.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-09-09"), 55.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-09-01"), 35.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-05-20"), 60.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-05-06"), 68.0 ) UNION ALL (
  SELECT "1" AS SKU, DATE("2017-04-15"), 136.0) UNION ALL (

  SELECT "2" AS SKU, DATE("2018-10-24"), 46.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-10-18"), 56.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-09-16"), 19.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-09-02"), 42.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-09-01"), 45.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-07-05"), 25.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-06-28"), 210.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-05-31"), 44.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-05-24"), 168.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-04-23"), 152.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-03-10"), 8.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-02-21"), 23.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-01-18"), 20.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2018-01-06"), 10.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-12-26"), 30.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-11-09"), 1240.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-11-03"), 323.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-10-21"), 123.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-09-30"), 444.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-09-09"), 555.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-08-01"), 35.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-06-20"), 6.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-05-06"), 68.0 ) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-04-15"), 136.0) UNION ALL (
  SELECT "2" AS SKU, DATE("2017-04-09"), 136.0)
)

SELECT 
  SKU, 
  CalendarFullDate, 
  SUM(DailySalesQty) OVER(win)
FROM
  samples WINDOW win AS (
    PARTITION BY
      SKU
    ORDER BY
      CalendarFullDate 
    RANGE BETWEEN DATE_TRUNC(CalendarFullDate,INTERVAL 364 DAY) AND CalendarFullDate)

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

Возможно ли это даже при использовании окон?Это хороший чистый способ сделать это, но не уверен, смогу ли я выразить такое условие для оконного агрегата?

Примечание: это урезанная версия реальных данных, которая имеет 5 полей в качестве раздела, и20 странных показателей для агрегирования, и это огромный набор данных (1 ТБ), поэтому мы хотим, чтобы он также был эффективным.

Мысли?

Приветствия!

1 Ответ

0 голосов
/ 22 ноября 2018

Ниже приведено описание BigQuery Standard SQL

#standardSQL
SELECT 
    SKU, 
    CalendarFullDate,
    SUM(DailySalesQty) OVER(win) SalesQty365days
FROM (
  SELECT 
    SKU, 
    CalendarFullDate, 
    DailySalesQty,
    UNIX_DATE(CalendarFullDate) unix_days
  FROM samples 
)
WINDOW win AS (
  PARTITION BY SKU ORDER BY unix_days 
  RANGE BETWEEN 364 PRECEDING AND CURRENT ROW
)

. Хитрость заключается в том, чтобы перевести поле CalendarFullDate типа DATE в число INTEGER, начиная с эпохи, чтобы его можно было использовать в ORDER BY и RANGE.части выражения ОКНА

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...