使用 Oracle SQL 来自嵌套 table 的移动平均线

Moving Average from nested table using Oracle SQL

我正在尝试根据以下案例找到正确的 sql 查询。

customer_id unit_id NAV DATE
16 1254 10 2020-05-01
17 1253 20 2020-05-02
18 1253 30 2020-05-03
16 1254 20 2020-05-02
16 1254 30 2020-05-03
17 1253 20 2020-05-02
17 1255 30 2020-05-03
16 1254 20 2020-05-04

从上面的 table 中,AVERAGE_NAV 可以通过自购买第一个日期单位以来的移动平均线找到。因此,如果我想为 customer_idunit_id 的特定数据从 table ACCOUNTBALANCE,我在下面使用这个查询。

SELECT
    ACCBAL.CUSTOMER_ID,
    ACCBAL.UNITTRUST_ID,
    ACCBAL.INVACCT_ID,
    ACCBAL.NAV,
    AVG(ACCBAL.NAV)
        OVER (
            ORDER BY ACCBAL.BALANCEDATE
            RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ),
    ACCBAL.CREATED_DATE
FROM WMS_UT_ACCOUNTBAL ACCBAL
WHERE
    ACCBAL.CUSTOMER_ID=16 AND
    ACCBAL.UNITTRUST_ID=1254

您可以在下面的 link 中看到查询的图片。 query image

查询结果如下图

customer_id unit_id NAV DATE Average_NAV
16 1254 10 2020-05-01 10
16 1254 20 2020-05-02 15
16 1254 30 2020-05-03 20
16 1254 20 2020-05-04 20

我的问题是,找到 average_NAV 与所有组合不同的 customer_id 和 unit_id 的查询是什么,就像下面的 table 一样。

customer_id unit_id NAV DATE average_NAV
16 1254 10 2020-05-01 10
17 1253 20 2020-05-02 20
18 1253 30 2020-05-03 30
16 1254 20 2020-05-02 15
16 1254 30 2020-05-03 20
17 1253 20 2020-05-02 20
17 1255 30 2020-05-03 30
16 1254 20 2020-05-04 20

average_NAV必须根据同一customer_id和unitrust_id的查询结果从第一次购买开始。您可以看到 customer_id=17 和 unit_id=1255 的 average_NAV=30 与 NAV 相同,因为它是第一次购买那些特定的 customer_id 和 unit_id 2020-05-03。 主要障碍是我如何在外部 SELECT 中使用 where 子句,因为它在 oracle sql.

中被禁止

我已经使用了 CTE 方法 (WITH),但仍然没有像下面预期的那样。

WITH ACCBAL (CUSTOMER_ID,UNITTRUST_ID,NAV, CREATED_DATE) AS
    (SELECT ACCBAL1.CUSTOMER_ID, ACCBAL1.UNITTRUST_ID,
            ACCBAL1.NAV, ACCBAL1.CREATED_DATE
     FROM WMS_UT_ACCOUNTBAL ACCBAL1),
    ACCBAL_AVERAGE_NAV (AVERAGE_NAV) AS
        (SELECT AVG(ACCBAL2.NAV) OVER
        (ORDER BY ACCBAL2.CREATED_DATE RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
            FROM WMS_UT_ACCOUNTBAL ACCBAL2
        WHERE ACCBAL2.UNITTRUST_ID=ACCBAL.UNITTRUST_ID
            AND ACCBAL2.CUSTOMER_ID=ACCBAL.CUSTOMER_ID)
SELECT * FROM ACCBAL,ACCBAL_AVERAGE_NAV;

上面的查询不起作用,因为它在 WHERE 子句中给出了无效标识符的错误。

谁能帮帮我?真的很感激。谢谢

  1. 您可以在 ORDER BY 之前包含 PARTITION BY 子句。
  2. 测试于 db<>fiddle
SELECT
    ACCBAL.CUSTOMER_ID,
    ACCBAL.UNITTRUST_ID,
    -- ACCBAL.INVACCT_ID,
    ACCBAL.NAV,
    ACCBAL.CREATED_DATE,
    AVG(ACCBAL.NAV)
        OVER (
            PARTITION BY ACCBAL.CUSTOMER_ID, ACCBAL.UNITTRUST_ID 
            ORDER BY ACCBAL.CREATED_DATE
        )
FROM WMS_UT_ACCOUNTBAL ACCBAL;