如何计算 Presto 中每个第 n 行的 window 函数?
How to compute window function for each nth row in Presto?
我正在使用包含时间序列数据的 table,每个用户每分钟一行。
我想在 N 个日历日的滚动 window 上计算一些聚合函数。
这是通过
实现的
SELECT
SOME_AGGREGATE_FUN(col) OVER (
PARTITION BY user_id
ORDER BY timestamp
ROWS BETWEEN (60 * 24 * N) PRECEDING AND CURRENT ROW
) as my_col
FROM my_table
但是,我只对每天的结果感兴趣。
即我希望 window 仅在 00:00:00 处计算,但我希望 window 本身包含所有要传递到我的聚合函数中的每分钟数据。
现在我正在这样做:
WITH agg_results AS (
SELECT
SOME_AGGREGATE_FUN(col) OVER (
PARTITION BY user_id
ORDER BY timestamp_col
ROWS BETWEEN (60 * 24 * N) PRECEDING AND CURRENT ROW
)
FROM my_table
)
SELECT * FROM agg_results
WHERE
timestamp_col = DATE_TRUNC('day', "timestamp_col")
这在理论上是可行的,但它会进行 60 * 24 次必要的计算,导致查询非常慢。
本质上,我试图找到一种方法来根据条件创建正确的 window 绑定跳过行。或者,如果实现起来更简单,则每第 n 行(因为我每天的行数都是固定的)。
我认为 window 函数不可能做到这一点。您可以改用子查询,假设您的聚合函数也可以用作常规聚合函数(即,没有 OVER()
子句):
select
timestamp_col,
(
select some_aggregate_fun(t1.col)
from my_table t1
where
t1.user_id = t.user_id
and t1.timestamp_col >= t.timestamp_col - interval '1' day
and t1.timestamp_col <= t.timestamp_col
)
from my_table t
where timestamp_col = date_trunc('day', timestamp_col)
虽然我不确定这会比您的原始查询执行得更好;您可能需要根据您的实际数据集对其进行评估。
您可以将 interval '1' day
更改为您要使用的实际间隔。
我正在使用包含时间序列数据的 table,每个用户每分钟一行。
我想在 N 个日历日的滚动 window 上计算一些聚合函数。
这是通过
实现的SELECT
SOME_AGGREGATE_FUN(col) OVER (
PARTITION BY user_id
ORDER BY timestamp
ROWS BETWEEN (60 * 24 * N) PRECEDING AND CURRENT ROW
) as my_col
FROM my_table
但是,我只对每天的结果感兴趣。
即我希望 window 仅在 00:00:00 处计算,但我希望 window 本身包含所有要传递到我的聚合函数中的每分钟数据。
现在我正在这样做:
WITH agg_results AS (
SELECT
SOME_AGGREGATE_FUN(col) OVER (
PARTITION BY user_id
ORDER BY timestamp_col
ROWS BETWEEN (60 * 24 * N) PRECEDING AND CURRENT ROW
)
FROM my_table
)
SELECT * FROM agg_results
WHERE
timestamp_col = DATE_TRUNC('day', "timestamp_col")
这在理论上是可行的,但它会进行 60 * 24 次必要的计算,导致查询非常慢。
本质上,我试图找到一种方法来根据条件创建正确的 window 绑定跳过行。或者,如果实现起来更简单,则每第 n 行(因为我每天的行数都是固定的)。
我认为 window 函数不可能做到这一点。您可以改用子查询,假设您的聚合函数也可以用作常规聚合函数(即,没有 OVER()
子句):
select
timestamp_col,
(
select some_aggregate_fun(t1.col)
from my_table t1
where
t1.user_id = t.user_id
and t1.timestamp_col >= t.timestamp_col - interval '1' day
and t1.timestamp_col <= t.timestamp_col
)
from my_table t
where timestamp_col = date_trunc('day', timestamp_col)
虽然我不确定这会比您的原始查询执行得更好;您可能需要根据您的实际数据集对其进行评估。
您可以将 interval '1' day
更改为您要使用的实际间隔。