0

我们有一个包含 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 天(不包括周末)的滚动平均交易量。如果是第 1 天,则平均值等于当天的交易数量,如果是第 2 天,则等于 (n1+n2)/2,第 3 天则等于 (n1+n2+n3 )/3 等等。

任何帮助将不胜感激。

4

3 回答 3

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<>小提琴

于 2019-09-05T07:44:50.320 回答
0

你可以试试这个。首先,您需要从列表中过滤掉周末,因为在您的问题中您想找到 last 的记录180 days excluding weekends。为了获得days name我们使用的日期TO_CHAR,并确保它会读为英语,我们将添加'NLS_DATE_LANGUAGE=English'

获得列表后,您可以简单地过滤 180 条记录以进行计算。为此,您可能有几种方法,例如,top等。我正在使用。所以最终的示例代码将是这样的。row_numberlimitrow_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 的改进。

于 2019-09-05T06:46:44.460 回答
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

干杯!!

于 2019-09-05T07:27:08.747 回答