有计算移动平均数的原始数据:
2020-04-01 210
2020-04-02 125
2020-04-03 150
2020-04-04 230
2020-04-05 200
2020-04-06 25
2020-04-07 215
2020-04-08 300
2020-04-09 250
2020-04-10 220
在Excel中计算5天的移动平均线:
从
c1
到 c5
没有数据。(在 c5 中,=AVERAGE(B1:B5)
是公式,c6
到 c10
的逻辑相同。)
现在用 postgres 来计算。
postgres=# create table sales(order_date date,sale int);
postgres=# insert into sales values('2020-04-01',210),
('2020-04-02',125),('2020-04-03',150),('2020-04-04',230),
('2020-04-05',200),('2020-04-10',220),('2020-04-06',25),
('2020-04-07',215),('2020-04-08',300),('2020-04-09',250);
postgres=# select * from sales;
order_date | sale
------------+------
2020-04-01 | 210
2020-04-02 | 125
2020-04-03 | 150
2020-04-04 | 230
2020-04-05 | 200
2020-04-10 | 220
2020-04-06 | 25
2020-04-07 | 215
2020-04-08 | 300
2020-04-09 | 250
计算:
SELECT a.order_date,a.sale,
AVG(a.sale)
OVER(ORDER BY a.order_date ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)
AS avg_sales
FROM sales a ;
order_date | sale | avg_sales
------------+------+----------------------
2020-04-01 | 210 | 210.00
2020-04-02 | 125 | 167.50
2020-04-03 | 150 | 161.66
2020-04-04 | 230 | 178.75
2020-04-05 | 200 | 183.00
2020-04-06 | 25 | 146.00
2020-04-07 | 215 | 164.00
2020-04-08 | 300 | 194.00
2020-04-09 | 250 | 198.00
2020-04-10 | 220 | 202.00
如何用psql命令得到如下结果?
order_date | sale | avg_sales
------------+------+----------------------
2020-04-01 | 210 |
2020-04-02 | 125 |
2020-04-03 | 150 |
2020-04-04 | 230 |
2020-04-05 | 200 | 183.00
2020-04-06 | 25 | 146.00
2020-04-07 | 215 | 164.00
2020-04-08 | 300 | 194.00
2020-04-09 | 250 | 198.00
2020-04-10 | 220 | 202.00
SELECT order_date, sale,
CASE WHEN ROW_NUMBER() OVER (ORDER BY order_date) >= 5
THEN AVG(sale) OVER (ORDER BY order_date ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)
END AS avg_sales FROM SALES
在此 SQL 查询中,我们想要计算表中每一行的平均销售额,但我们希望平均值从第五行开始。
我们有一个名为“sales”的表,其中包含“order_date”和“sale”等列。
我们使用 ROW_NUMBER() 函数根据“order_date”列的顺序为表中的每一行分配一个唯一的编号。
接下来,我们检查行号是否大于或等于 5。如果是,我们计算当前行和前四行的销售值的平均值。如果没有,我们将“avg_sales”列留空(NULL)。
最后,我们为“sales”表中的每一行选择“order_date”、“sale”和计算出的“avg_sales”。 “avg_sales”列仅包含从第五行开始的值,前面的行在该列中将包含 NULL。
所以,简单来说,这个查询计算每天的平均销售额,但它只从第五天开始计算平均值,将前面的日子留空。