我正在研究名为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
;
答案 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)
中。