最近30天的平均值,不包括当前记录(混合日期和基于行的条件)

时间:2019-06-25 15:16:30

标签: oracle window-functions

我正在研究名为CRD_TRX_SYAMT_AVG_30d的列,该列满足以下条件:

  • 根据SYSTEMAMOUNT计算过去30天内TRXHOSTDATETIME列的平均值
  • 排除RESPONSECODE不是00的行
  • 不包括当前记录

下面有完整的示例数据。而且我已将其粘贴到DB Fiddle中,但是存在一个阻止代码在此处运行的问题。对我来说,它在SQL Developer中运行良好,但产生了意外的结果。

我尝试用1 PRECEDING代替CURRENT ROW,但是按照我的理解,不可能混合使用区间和范围。列CRD_TRX_SYAMT_AVG_30_trx_exc使用基于行的条件(行数在30到1之间的行),这很好用。因此,问题仅在于CRD_TRX_SYAMT_AVG_30d

如何将条件更改为以下内容?

RANGE BETWEEN INTERVAL '30' DAY PRECEDING AND 1 PRECEDING

https://dbfiddle.uk/?rdbms=oracle_18&fiddle=471da47ef5df960b67e427053e7642d4

-- DATE formatting
alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';

-- DROP and CREATE TABLE
DROP TABLE TMP_EXA_RSS_ISS_AUT_S_100CRD_T;

CREATE TABLE "RAI"."TMP_EXA_RSS_ISS_AUT_S_100CRD_T" 
 (  "ID_KEY_HASH" VARCHAR2(10), 
"TRXHOSTDATETIME" DATE, 
"SYSTEMAMOUNT" NUMBER(10,1), 
"RESPONSECODE" CHAR(2)
 );

 -- fill entire table
DECLARE
  nTRX NUMBER(10) := 100;
BEGIN
FOR i IN 1 .. nTRX LOOP
  INSERT INTO tmp_exa_RSS_ISS_AUT_S_100CRD_T VALUES
  (
    FLOOR(DBMS_RANDOM.VALUE (1, 4)), -- ID_KEY_HASH
    TO_DATE('01.01.2018', 'DD.MM.YYYY') + dbms_random.value(0, 60), -- TRXHOSTDATETIME
    FLOOR(DBMS_RANDOM.VALUE (1, 10)) * 100, -- SYSTEMAMOUNT
    CASE round(dbms_random.value(1,11)) 
            WHEN 1 THEN '55' 
            WHEN 2 THEN '88'
            ELSE '00'
       END -- RESPONSECODE 
  );
END LOOP;
END;
/

-- review all data created
SELECT * FROM tmp_exa_RSS_ISS_AUT_S_100CRD_T ORDER BY ID_KEY_HASH, TRXHOSTDATETIME;


-- example features:

SELECT ID_KEY_HASH, TRXHOSTDATETIME, SYSTEMAMOUNT, RESPONSECODE,
ROUND(AVG(
  CASE WHEN ((SYSTEMAMOUNT > 0) AND (RESPONSECODE = '00')  ) THEN SYSTEMAMOUNT ELSE NULL END
) OVER (PARTITION BY ID_KEY_HASH ORDER BY TRXHOSTDATETIME 
                        RANGE BETWEEN INTERVAL '30' DAY PRECEDING AND CURRENT ROW), 2)  AS CRD_TRX_SYAMT_AVG_30d,
NVL( ROUND( 
  AVG(
      CASE WHEN ((SYSTEMAMOUNT > 0) AND (RESPONSECODE = '00')  ) THEN SYSTEMAMOUNT ELSE NULL END
      ) 
      OVER (PARTITION BY ID_KEY_HASH ORDER BY TRXHOSTDATETIME NULLS LAST 
      ROWS BETWEEN 30 PRECEDING AND 1 PRECEDING)
  , 2), 0 ) AS CRD_TRX_SYAMT_AVG_30_trx_exc
FROM tmp_exa_RSS_ISS_AUT_S_100CRD_T
ORDER BY ID_KEY_HASH, TRXHOSTDATETIME
;

1 个答案:

答案 0 :(得分:3)

如果复合Vec是唯一的(对于相同的ID_KEY_HASH,没有重复的日期时间),那么以下表达式将满足您的要求:

(ID_KEY_HASH, TRXHOSTDATETIME)

如果需要,可以将其包装在 avg(case when systemamount > 0 and responsecode = '00' then systemamount end) over (partition by id_key_hash order by TRXHOSTDATETIME range between interval '30' day preceding and interval '1' second preceding) 中。