我的
Postgresql 9.1数据库中有以下表格:
select * from ro; date | shop_id | amount -----------+----------+-------- 2013-02-07 | 1001 | 3 2013-01-31 | 1001 | 2 2013-01-24 | 1001 | 1 2013-01-17 | 1001 | 5 2013-02-10 | 1001 | 10 2013-02-03 | 1001 | 4 2012-12-27 | 1001 | 6 2012-12-20 | 1001 | 8 2012-12-13 | 1001 | 4 2012-12-06 | 1001 | 3 2012-10-29 | 1001 | 3
我试图获得一个移动平均数据,比较最近3个星期四的数据,而不包括当前的星期四.这是我的查询:
select date,shop_id,amount,extract(dow from date),avg(amount) OVER (PARTITION BY extract(dow from date) ORDER BY date DESC ROWS BETWEEN 0 PRECEDING AND 2 FOLLOWING) from ro where extract(dow from date) = 4
这是给出的结果
date | shop_id | amount | date_part | avg -----------+----------+--------+-----------+-------------------- 2013-02-07 | 1001 | 3 | 4 | 2.0000000000000000 2013-01-31 | 1001 | 2 | 4 | 2.6666666666666667 2013-01-24 | 1001 | 1 | 4 | 4.0000000000000000 2013-01-17 | 1001 | 5 | 4 | 6.3333333333333333 2012-12-27 | 1001 | 6 | 4 | 6.0000000000000000 2012-12-20 | 1001 | 8 | 4 | 5.0000000000000000 2012-12-13 | 1001 | 4 | 4 | 3.5000000000000000 2012-12-06 | 1001 | 3 | 4 | 3.0000000000000000
我预计
date | shop_id | amount | date_part | avg -----------+----------+--------+-----------+-------------------- 2013-02-07 | 1001 | 3 | 4 | 2.6666666666666667 2013-01-31 | 1001 | 2 | 4 | 4.0000000000000000 2013-01-24 | 1001 | 1 | 4 | 6.3333333333333333 2013-01-17 | 1001 | 5 | 4 | 6.0000000000000000 2012-12-27 | 1001 | 6 | 4 | 5.0000000000000000 2012-12-20 | 1001 | 8 | 4 | 2012-12-13 | 1001 | 4 | 4 | 2012-12-06 | 1001 | 3 | 4 |
SQL Fiddle
select "date",case when row_number() over (order by date) > 3 then avg(amount) OVER ( ORDER BY date DESC ROWS BETWEEN 1 following AND 3 FOLLOWING ) else null end from ( select * from ro where extract(dow from date) = 4 ) s
OP的查询是什么问题是帧规范:
ROWS BETWEEN 0 PRECEDING AND 2 FOLLOWING
除此之外,我的查询避免了在应用昂贵的窗口功能之前过滤星期四不必要的计算.
如果有必要通过shop_id进行分区,那么显然可以通过shop_id将分区添加到这两个函数avg和row_number.