使用 HQL 的滚动平均值

Rolling averages with HQL

这是我第一次 post 关于 SO。所以我完全有可能违反很多 posting 规则。如果是这种情况,请告诉我,我将确保不再重复。

我一直试图在 Hive 的同一查询中获得滚动平均值和绝对数,这就是我所拥有的。这在 Redshift 中完美运行,但在 Hive 中给了我一个错误。看起来 select 语句中的子查询不受支持。想知道我是否可以获得一些关于如何修改此查询以从 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    

您的示例中的技术称为相关子查询,并且往往非常慢。我建议使用带有范围子句的 window 函数。

首先,在子查询中,计算每一天的指标。然后在主select中使用window函数计算滚动sum/avg。 See more window function examples in the Redshift docs.

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
;