Oracle:获取过去30个工作日的平均数

时间:2017-10-25 14:31:32

标签: sql oracle

Oracle版 11g

我的表有类似的记录。

calendar_date   ID   record_count
25-OCT-2017      1   20
25-OCT-2017      2   40
25-OCT-2017      3   60
24-OCT-2017      1   70
24-OCT-2017      2   50
24-OCT-2017      3   10
20-OCT-2017      1   35
20-OCT-2017      2   60
20-OCT-2017      3   90
18-OCT-2017      1   80
18-OCT-2017      2   50
18-OCT-2017      3   45

,即对于每个ID,给定日历日有一个记录计数。这些日子连续,即周末/假日等可能缺少记录。在这些日子里,没有可用于任何ID的记录。但是,在工作日,每个ID都有可用的条目。

需要获取每个ID的最后30 business days的平均记录数

我想要这样的输出。 (不要超过价值观。这只是一个样本)

ID  avg_count_last_30
1    150
2    130
3    110

我想找出最有效的方法来做到这一点。我想过使用RANGE BETWEENROWS BETWEEN等,但不确定它会起作用。

当然,这样的查询不会有帮助,因为中间有假期。

select id, AVG(record_count) FROM mytable 
where calendar_date between SYSDATE - 30 and SYSDATE - 1
group by id;

我需要的是像

select id , AVG(record_count) FROM mytable 
    where calendar_date between last_30th_business_day and last_business_day
    group by id;

last_30th_business_daycount(DISTINCT business_days )从最近一个工作日开始,直到我算上30个。

last_business_day 最近一个工作日

想了解专家对此和最佳方法的意见。

1 个答案:

答案 0 :(得分:1)

根据您的评论尝试以下内容:

WITH mytable (calendar_date, ID, record_count) AS (
    SELECT TO_DATE('25-10-2017', 'DD-MM-YYYY'), 1, 20 FROM dual UNION ALL
    SELECT TO_DATE('25-10-2017', 'DD-MM-YYYY'), 2, 40 FROM dual UNION ALL
    SELECT TO_DATE('25-10-2017', 'DD-MM-YYYY'), 3, 60 FROM dual UNION ALL
    SELECT TO_DATE('24-10-2017', 'DD-MM-YYYY'), 1, 70 FROM dual UNION ALL
    SELECT TO_DATE('24-10-2017', 'DD-MM-YYYY'), 2, 50 FROM dual UNION ALL
    SELECT TO_DATE('24-10-2017', 'DD-MM-YYYY'), 3, 10 FROM dual UNION ALL
    SELECT TO_DATE('20-10-2017', 'DD-MM-YYYY'), 1, 35 FROM dual UNION ALL
    SELECT TO_DATE('20-10-2017', 'DD-MM-YYYY'), 2, 60 FROM dual UNION ALL
    SELECT TO_DATE('20-10-2017', 'DD-MM-YYYY'), 3, 90 FROM dual UNION ALL
    SELECT TO_DATE('18-10-2017', 'DD-MM-YYYY'), 1, 80 FROM dual UNION ALL
    SELECT TO_DATE('18-10-2017', 'DD-MM-YYYY'), 2, 50 FROM dual UNION ALL
    SELECT TO_DATE('18-10-2017', 'DD-MM-YYYY'), 3, 45 FROM dual),
t AS (
    SELECT calendar_date, ID, record_count,
        ROW_NUMBER() OVER (PARTITION BY ID ORDER BY calendar_date desc) AS RN
    FROM mytable)
SELECT ID, AVG(RECORD_COUNT) 
FROM t
WHERE rn <= 30
group by ID;
相关问题