计算平均180天的滚动

时间:2019-09-05 06:23:01

标签: sql oracle rolling-average

我们有一个表,其中包含TXN_DATE和NO_OF_TXNS列。下面是示例数据:

TXN_DATE           NO_OF_TXNS
25-AUG-19             0
26-AUG-19             1000
27-AUG-19             1500
28-AUG-19             1800
29-AUG-19             1100
30-AUG-19             1400

我们要计算最近180天(不包括周末)的交易滚动平均值。如果是第一天,则平均值将等于当天的交易数量;如果是第二天,则平均值将等于(n1 + n2)/ 2;如果是第二天,则平均值将等于(n1 + n2 + n3 )/ 3等。

我们将不胜感激任何帮助。

3 个答案:

答案 0 :(得分:3)

您可以在RANGE窗口中使用分析功能。您还可以使用TXN_DATE - TRUNC( TXN_DATE, 'IW' )来查找自ISO周开始(每周总是从星期一开始)以来的一周中的天数,这意味着您的查询不依赖于特定的语言或会话参数(每个参数用户可以在他们的会话中进行更改,并将语言更改为TO_CHAR(一周中的某几天没有给出预期的输出)。

SELECT TXN_DATE,
       AVG( NO_OF_TXNS ) OVER (
         ORDER BY TXN_DATE
         RANGE BETWEEN 180 PRECEDING
               AND     0   PRECEDING
       ) AS avg_no_of_txns
FROM   table_name
WHERE  NOT ( TXN_DATE - TRUNC( TXN_DATE, 'IW' ) BETWEEN 5 AND 7 );

如果您希望将其限制在最近180天的数据中,则需要找到平均值,然后再进行过滤:

SELECT *
FROM   (
  SELECT TXN_DATE,
         AVG( NO_OF_TXNS ) OVER (
           ORDER BY TXN_DATE
           RANGE BETWEEN 180 PRECEDING
                 AND     0   PRECEDING
         ) AS avg_no_of_txns
  FROM   table_name
  WHERE  NOT ( TXN_DATE - TRUNC( TXN_DATE, 'IW' ) BETWEEN 5 AND 7 )
)
WHERE TXN_DATE >= TRUNC( SYSDATE ) - INTERVAL '180' DAY(3);

db<>fiddle

答案 1 :(得分:0)

您可以尝试一下。首先,您需要从列表中过滤掉周末,因为在您的问题中,您想查找最近180 days excluding weekends的记录。为了获取日期days name,我们使用TO_CHAR,并确保将其读为英语,我们将添加'NLS_DATE_LANGUAGE=English'

一旦有了列表,就可以简单地过滤180条记录进行计算。为此,您可能有几种方法,例如toprow_numberlimit等。我正在使用row_number。所以最终的示例代码将是这样。

with record ( SLNO, TXN_DATE, NO_OF_TXNS ) AS 
( 
     SELECT ROW_NUMBER() OVER (ORDER BY TXN_DATE DESC) AS SLNO,
            TXN_DATE,
            NO_OF_TXNS
     FROM   TABLE 
     WHERE  TO_CHAR(TXN_DATE,'DY', 'NLS_DATE_LANGUAGE=English') NOT IN ('SAT', 'SUN') 
)
select TXN_DATE,
       NO_OF_TXNS, 
       (select avg(t.NO_OF_TXNS) from record t where t.TXN_DATE<=t1.TXN_DATE
and t.SLNO<180) as Sum 
from record t1 

感谢@WernfriedDomscheit的改进。

答案 2 :(得分:0)

您可以使用分析函数,并且我会避免使用行前置运算符,因为如果输入缺少一或多天,它不会给出确切的结果,因此最好使用WHERE子句来获取最近180天。

SELECT TXN_DATE,
       AVG(NO_OF_TXNS) OVER (ORDER BY TXN_DATE) AS ROLLING_AVERAGE
  FROM YOUR_TABLE
 WHERE TO_CHAR(TXN_DATE,'DY') NOT IN ('SAT','SUN')
   AND TRUNC(TXN_DATE) >= TRUNC(SYSDATE) - 180

干杯!