如何在 Big Query 的移动窗口中找到特定组中三个最大值的平均值?
Posted
技术标签:
【中文标题】如何在 Big Query 的移动窗口中找到特定组中三个最大值的平均值?【英文标题】:How to find the average of the three maximum values in a specific group in a moving window in Big Query? 【发布时间】:2021-12-02 21:38:48 【问题描述】:我有一个数据集,如下表所示。我想在按 id 分组的滚动 12 个月窗口中找到最大三个值的平均值。
id date value
id1 2020/01/01 500
id1 2021/02/01 300
id1 2021/03/01 150
id1 2021/08/01 100
id1 2021/12/01 400
id2 2020/01/01 50
id2 2020/02/01 900
id2 2021/12/01 100
所以我的预期输出是:
id date value
id1 2020/01/01 500
id1 2021/02/01 300
id1 2021/03/01 225
id1 2021/08/01 183.33
id1 2021/12/01 283.33
id2 2020/01/01 50
id2 2020/02/01 500
id2 2021/12/01 100
即对于id1
2021/12/01
:(400+300+150)/3 = 283.33,这是组 ID1 滚动 12 个月窗口中三个最大值的平均值。
我设法做到了这一点:
CREATE TEMP FUNCTION avg_array(arr ANY TYPE) AS ((
SELECT AVG(val) FROM(
SELECT val FROM UNNEST(arr) val ORDER BY val DESC LIMIT 3)
)
);
SELECT id, date, avg_array(val_arr)
FROM (
SELECT
id, date, ARRAY_AGG(value) OVER (
PARTITION BY id
ORDER BY id, date DESC ROWS BETWEEN CURRENT ROW AND 11 FOLLOWING
) as val_arr
FROM `table` )
这可行,但我觉得必须有更好的方法来做到这一点。具体来说,我不知道如何从 OVER 中获取最大三个的平均值,而不是创建一个单独的函数。
(如果无法将日期窗口与查找最大值相结合,那么知道如何在不创建单独函数的情况下找到任何group by
组中最大值三个的平均值也很有用)
`
【问题讨论】:
【参考方案1】:在您的代码中,缺少“PARTITION BY id,EXTRACT(YEAR FROM date)”语句中的日期年份。
CREATE TEMP FUNCTION avg_array(arr ANY TYPE) AS ((
SELECT AVG(val) FROM(
SELECT val FROM UNNEST(arr) val ORDER BY val DESC LIMIT 3))
);
SELECT id, date, avg_array(val_arr)
FROM (
SELECT
id, date, ARRAY_AGG(value) OVER (
PARTITION BY id,EXTRACT(YEAR FROM date)
ORDER BY id, date DESC ROWS BETWEEN CURRENT ROW AND 11 FOLLOWING
) as val_arr
FROM `table` )
order by id,date asc
在这里,你可以看到一个示例代码来获取一个组的最多 3 个数字:
select id,AVG(value) as vg from (
select id,date,value from (
select id, date, value from `table`
order by value desc) a limit 3
) b group by id
你可以在this link看到更多关于over function的信息。
【讨论】:
【参考方案2】:考虑以下方法
select id, date,
(select round(avg(value), 2) from (
select value from t.arr value
order by value desc
limit 3
)) value
from (
select *, array_agg(value) over last_12_month arr from table
window last_12_month as (partition by id
order by 12 * (extract(year from date)) + extract(month from date)
range between 11 preceding and current row
)
) t
如果应用于您问题中的样本数据 - 输出是
【讨论】:
你试过了吗?以上是关于如何在 Big Query 的移动窗口中找到特定组中三个最大值的平均值?的主要内容,如果未能解决你的问题,请参考以下文章
BIG QUERY SQL:使用移动参考标记滑动时间窗口上的日期
如何将 .gz 文件上传到 Google Big Query?