Hive 的加权移动平均值 SQL
weighted moving average with Hive SQL
给定如下所示的 Hive table 我想计算加权移动平均值。在 table 中,1 是这种加权移动平均线的示例。每列的值为
col_value = (1 * n) + (0.75 * n-1) + (0.5 * n-2) + (0.25 * n-3)
where n is the value at the current row, n-1 the value at the above row, etc.
corresponding Wikipedia section
上有关加权移动平均线的更多信息
像这样计算移动平均线后我卡住了:
代码示例 1:到目前为止的查询
SELECT
*,
AVG (value) OVER (
ORDER BY
id
ROWS BETWEEN
3 PRECEDING AND CURRENT ROW
FROM
table
Table 1:
id value weighted_moving_average code_sample_1
...
11 0 0 0
12 1 1 0.25
13 0 0.75 0.25
14 0 0.5 0.25
15 0 0.25 0.25
16 0 0 0
...
这并不花哨,但它是一个开始。
SELECT
*,
(SUM (value*0.25) OVER (ORDER BY id ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) +
SUM (value*0.25) OVER (ORDER BY id ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) +
SUM (value*0.25) OVER (ORDER BY id ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +
value * 0.25) /
COUNT (value) OVER (ORDER BY id ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
FROM
table;
如果您希望 window 大小可以轻松更改,那么实现方式将大不相同。
(请注意,我是在 sql-server because I am not aware of any website I can test hive SQL 中开发的。您可能需要调整一些语法。)
Declare @thisManyRows int = 3;
With rowNumber_cte As (
Select
id,
[Value],
RowNo = Row_Number() Over (Order By id)
From Table1),
windows_cte As (
Select
b_id = b.id,
j_id = j.id,
j.[Value],
RowNo2 = @thisManyRows + 1 - Row_Number() Over (Partition By b.id Order By j.id desc),
n = Count(j.[Value]) Over (Partition By b.id)
From rowNumber_cte As b
Join rowNumber_cte As j On j.RowNo Between b.RowNo - @thisManyRows + 1 And b.RowNo)
Select
id = b_id,
[Value] = Sum(Case When b_id = j_id Then [Value] Else Null End),
WeightedAverage = Sum([Value] * 1.0 * (RowNo2 *1.0 / @thisManyRows)) / Min(n)
From windows_cte
Group By b_id;
我将解释它的作用,因为它有点神秘:
- 将变量设置为移动平均值要考虑的行数(包括当前行)。
- 在
rowNumber_cte
中我们分配了一个行号,我们这样做是因为我们不假设 id
将是连续的。
- 在
windows_cte
中,我们将 rowNumber_cte
自身连接起来,这样每一行都连接到构成它的所有行 window 计算(参考 @thisManyRows
变量。此 cte 还引入了一个新的 RowNo2
字段,该字段基本上最终将成为分数的分子,该行的值对加权移动平均值的贡献(即当前行,如果 window 是 4 将具有 RowNo2 = 4
并且将具有 4/4 权重)。
windows_cte
还计算 window 中的行数,以更好地处理数据开头没有完整 window.[=35= 的行]
- 最后的 select 分组
id
,将 window 中每一行的 [Value]
乘以它的权重,然后除以 window 中的行数window: n
.
给定如下所示的 Hive table 我想计算加权移动平均值。在 table 中,1 是这种加权移动平均线的示例。每列的值为
col_value = (1 * n) + (0.75 * n-1) + (0.5 * n-2) + (0.25 * n-3)
where n is the value at the current row, n-1 the value at the above row, etc.
corresponding Wikipedia section
上有关加权移动平均线的更多信息像这样计算移动平均线后我卡住了:
代码示例 1:到目前为止的查询
SELECT
*,
AVG (value) OVER (
ORDER BY
id
ROWS BETWEEN
3 PRECEDING AND CURRENT ROW
FROM
table
Table 1:
id value weighted_moving_average code_sample_1
...
11 0 0 0
12 1 1 0.25
13 0 0.75 0.25
14 0 0.5 0.25
15 0 0.25 0.25
16 0 0 0
...
这并不花哨,但它是一个开始。
SELECT
*,
(SUM (value*0.25) OVER (ORDER BY id ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) +
SUM (value*0.25) OVER (ORDER BY id ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) +
SUM (value*0.25) OVER (ORDER BY id ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +
value * 0.25) /
COUNT (value) OVER (ORDER BY id ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
FROM
table;
如果您希望 window 大小可以轻松更改,那么实现方式将大不相同。
(请注意,我是在 sql-server because I am not aware of any website I can test hive SQL 中开发的。您可能需要调整一些语法。)
Declare @thisManyRows int = 3;
With rowNumber_cte As (
Select
id,
[Value],
RowNo = Row_Number() Over (Order By id)
From Table1),
windows_cte As (
Select
b_id = b.id,
j_id = j.id,
j.[Value],
RowNo2 = @thisManyRows + 1 - Row_Number() Over (Partition By b.id Order By j.id desc),
n = Count(j.[Value]) Over (Partition By b.id)
From rowNumber_cte As b
Join rowNumber_cte As j On j.RowNo Between b.RowNo - @thisManyRows + 1 And b.RowNo)
Select
id = b_id,
[Value] = Sum(Case When b_id = j_id Then [Value] Else Null End),
WeightedAverage = Sum([Value] * 1.0 * (RowNo2 *1.0 / @thisManyRows)) / Min(n)
From windows_cte
Group By b_id;
我将解释它的作用,因为它有点神秘:
- 将变量设置为移动平均值要考虑的行数(包括当前行)。
- 在
rowNumber_cte
中我们分配了一个行号,我们这样做是因为我们不假设id
将是连续的。 - 在
windows_cte
中,我们将rowNumber_cte
自身连接起来,这样每一行都连接到构成它的所有行 window 计算(参考@thisManyRows
变量。此 cte 还引入了一个新的RowNo2
字段,该字段基本上最终将成为分数的分子,该行的值对加权移动平均值的贡献(即当前行,如果 window 是 4 将具有RowNo2 = 4
并且将具有 4/4 权重)。 windows_cte
还计算 window 中的行数,以更好地处理数据开头没有完整 window.[=35= 的行]- 最后的 select 分组
id
,将 window 中每一行的[Value]
乘以它的权重,然后除以 window 中的行数window:n
.