POSTGRES - 前4个工作日的平均值

时间:2018-03-15 19:03:53

标签: sql postgresql postgresql-9.4

您好我正在尝试计算前4个星期二的平均值。我有每日销售数据,我正在计算同一工作日前四周的平均值。

附件是我的数据集外观的快照

Sample view of the dataset

现在3月6日,我想知道过去4周的平均值是多少(即2月6日,2月13日,2月20日和2月27日)。需要将此值分配给每月平均列

我正在使用PostGres数据库。

谢谢

2 个答案:

答案 0 :(得分:0)

您可以使用窗口功能:

select t.*,
       avg(dailycount) over (partition by seller_name, day
                             order by date
                             rows between 3 preceding and current row
                            ) as avg_4_weeks
from t
where day = 'Tuesday';

这假设“前4周”是当前日期加上前三周。如果它在前一周开始,则只需要改变窗口条款:

select t.*,
       avg(dailycount) over (partition by seller_name, day
                             order by date
                             rows between 4 preceding and 1 preceding
                            ) as avg_4_weeks
from t
where day = 'Tuesday';

答案 1 :(得分:0)

我决定也发布我的答案,供其他人搜索。我的答案将允许您输入任何日期并获得前4周的平均值(当天+前3周匹配当天)。

SQL Fiddle

PostgreSQL 9.3架构设置

CREATE TABLE sales (sellerName varchar(10), dailyCount int, saleDay date) ;

INSERT INTO sales (sellerName, dailyCount, saleDay)
SELECT 'ABC',10,to_date('2018-03-15','YYYY-MM-DD') UNION ALL /* THIS ONE */
SELECT 'ABC',11,to_date('2018-03-14','YYYY-MM-DD') UNION ALL 
SELECT 'ABC',12,to_date('2018-03-12','YYYY-MM-DD') UNION ALL
SELECT 'ABC',13,to_date('2018-03-11','YYYY-MM-DD') UNION ALL
SELECT 'ABC',14,to_date('2018-03-10','YYYY-MM-DD') UNION ALL
SELECT 'ABC',15,to_date('2018-03-09','YYYY-MM-DD') UNION ALL
SELECT 'ABC',16,to_date('2018-03-08','YYYY-MM-DD') UNION ALL /* THIS ONE */
SELECT 'ABC',17,to_date('2018-03-07','YYYY-MM-DD') UNION ALL
SELECT 'ABC',18,to_date('2018-03-06','YYYY-MM-DD') UNION ALL
SELECT 'ABC',19,to_date('2018-03-05','YYYY-MM-DD') UNION ALL
SELECT 'ABC',20,to_date('2018-03-04','YYYY-MM-DD') UNION ALL
SELECT 'ABC',21,to_date('2018-03-03','YYYY-MM-DD') UNION ALL
SELECT 'ABC',22,to_date('2018-03-02','YYYY-MM-DD') UNION ALL
SELECT 'ABC',23,to_date('2018-03-01','YYYY-MM-DD') UNION ALL /* THIS ONE */
SELECT 'ABC',24,to_date('2018-02-28','YYYY-MM-DD') UNION ALL
SELECT 'ABC',25,to_date('2018-02-22','YYYY-MM-DD') UNION ALL /* THIS ONE */
SELECT 'ABC',26,to_date('2018-02-15','YYYY-MM-DD') UNION ALL
SELECT 'ABC',27,to_date('2018-02-08','YYYY-MM-DD') UNION ALL
SELECT 'ABC',28,to_date('2018-02-01','YYYY-MM-DD')
;

现在查询

WITH theDay AS (
    SELECT to_date('2018-03-15','YYYY-MM-DD') AS inDate
)
SELECT AVG(dailyCount) AS totalCount /* 18.5 = (10(3/15)+16(3/8)+23(3/1)+25(2/22))/4 */
FROM sales
CROSS JOIN theDay
WHERE extract(dow from saleDay) = extract(dow from theDay.inDate)
  AND saleDay <= theDay.inDate
  AND saleDay >= theDay.inDate-INTERVAL '3 weeks' /* Since we want to include the entered 
      day, for the INTERVAL we need 1 less week than we want */

<强> Results

| totalcount |
|------------|
|       18.5 |