我在Postgres数据库中有一张数字表,我正在尝试为每一行计算前3行和后3行的范围(最大-最小值)。 给定一个测试表:
CREATE TABLE test_table AS (
SELECT
generate_series(1,100) id,
random()*generate_series(1,100) val
);
这可以通过以下查询完成:
SELECT
id,
MAX(val) OVER (
ORDER BY id
ROWS
BETWEEN 3 PRECEDING
AND 3 FOLLOWING
) -
MIN(val) OVER (
ORDER BY id
ROWS
BETWEEN 3 PRECEDING
AND 3 FOLLOWING
) val_range
FROM test_table;
但是OVER
子句是重复的。有没有一种方法可以改善查询并删除重复项?重复会影响性能吗?如果要为每个ID计算其他汇总,应该如何处理移动窗口?
我已经提出了以下查询以重用窗口,但是我不确定这是否是最佳方法。
WITH
windowed AS (
SELECT
id,
UNNEST(ARRAY_AGG(val) OVER (
ORDER BY id
ROWS
BETWEEN 3 PRECEDING
AND 3 FOLLOWING
)) val
FROM test_table
)
SELECT
id,
MAX(val)-MIN(val) val_range,
AVG(val) val_mean,
STDDEV(val) val_stddev
FROM windowed
GROUP BY id
ORDER BY id;
答案 0 :(得分:1)
您可以使用WINDOW
clause来缩短代码:
SELECT id
, MAX(val) OVER w -
MIN(val) OVER w AS val_range
FROM test_table
WINDOW w AS (ORDER BY id ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING);
但这几乎不影响性能。如果您也反复拼写,则Postgres将重用窗口框架。
相关: