Скользящие средние с HQL - PullRequest
0 голосов
/ 11 июня 2018

Это мой первый пост на SO.Так что вполне возможно, что я нарушаю множество правил публикации.Если это так, пожалуйста, дайте мне знать, и я постараюсь не повторять их.

Я пытался получить скользящее среднее и абсолютное число в одном запросе в Hive, и вот что у меня есть.Это прекрасно работало в Redshift, но в Hive вызвала ошибку.Похоже, подзапросы в операторах выбора не поддерживаются.Интересно, смогу ли я получить некоторые подсказки о том, как я могу изменить этот запрос, чтобы получить те же результаты из Hive.

    select 
            a.ds,
            a.traffic_source,
            a.device_type,
            count(distinct a.unique_id) as daily_deduped_visits_human,
            (select
                    count(distinct b.unique_id)
             from
                    scratch.unique_human_id b
             where
                    b.ds >= a.ds - 28
                    and b.ds <= a.ds
                    and a.traffic_source = b.traffic_source
                    and a.device_type = b.device_type
            )/28 as rolling_28_day_average_visits_human
    from
            scratch.unique_human_id a
    group by 1,2,3      

1 Ответ

0 голосов
/ 12 июня 2018

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

Сначала в подзапросе вычислите показатель для каждого дня.Затем в главном меню выберите использование оконных функций для расчета скользящей суммы / ср. См. Другие примеры оконных функций в документах Redshift.

SELECT a.ds
     , a.traffic_source
     , a.device_type
     , a.daily_deduped_visits_human
     , SUM(a.daily_deduped_visits_human) 
       OVER (PARTITION BY a.traffic_source, a.device_type 
             ORDER BY a.ds 
             ROWS BETWEEN 28 PRECEDING AND CURRENT ROW 
            ) AS rolling_28_day_total_visits_human
     , AVG(a.daily_deduped_visits_human) 
       OVER (PARTITION BY a.traffic_source, a.device_type 
             ORDER BY a.ds 
             ROWS BETWEEN 28 PRECEDING AND CURRENT ROW 
            ) AS rolling_28_day_average_visits_human
FROM (-- First calc the metric
      SELECT a.ds
           , a.traffic_source
           , a.device_type
           , COUNT(DISTINCT a.unique_id) AS daily_deduped_visits_human
      FROM scratch.unique_human_id a
      GROUP BY 1,2,3
      ) a
GROUP BY 1,2,3,4
ORDER BY a.traffic_source
     , a.device_type
     , a.ds
;
...