SQL - 需要递归计算解决方案

问题描述 投票:0回答:2

美好的一天,

有人可以协助如何实现以下目标吗?因此,我需要采用第一个“Addition”,即“Total_COB_Growth”+“Sum_of_Previous_Interest”,其中“Sum_of_Previous_Interest”取决于“Additions”的 LAG(如果有意义的话)。我无法在 SQL 中正确地将前一个值拖到每个连续行上。 (LAG() OVER (PARTITION BY 等) 一旦到达 2/3 线,就会返回零:

Table

因此,绿色列中的公式相互依赖,我很难弄清楚如何在 SQL 中对其进行编码。

第一个公式(在 Excel 中使用):

Additions =H4 + ROUND(E4,0)

Additions

第二个公式(在Excel中使用):

Previous_Interest =ROUNDDOWN(IF(C4=C3,G3*(1+D4/100)^(F4/12),0),0)

Previous Interest

我的感觉是,这将是通过 CTE 实现的,但我对这些的经验绝对为零,所以真的很期待解决这个问题。

提前致谢,这让我心碎。

我尝试了多个子查询来尝试获取在分区行上复制的值,但这没有帮助。

我们在 IBM i 上使用 DBeaver。

这是我尝试过但没有成功:

WITH #cte AS (
SELECT 
    UNIQUEKEY, 
    POL_NO, 
    NEW_TOTAL_RATE, 
    TOTAL_COB_GROWTH, 
    DURATION,
    0 AS "Additions to date TF",
    0 AS "Sum of previous with interest",
    1 AS RowNum
FROM 
    QRYLIB.temp_Test
UNION ALL
SELECT 
    t.UNIQUEKEY, 
    t.POL_NO, 
    t.NEW_TOTAL_RATE, 
    t.TOTAL_COB_GROWTH, 
    t.DURATION,
    CASE 
        WHEN t.DURATION = 0 THEN 
            LAG(#cte."Sum of previous with interest", 1, 0) OVER (PARTITION BY t.POL_NO ORDER BY t.UNIQUEKEY) + ROUND(t.TOTAL_COB_GROWTH, 0)
        ELSE 
            LAG(#cte."Sum of previous with interest", 1, 0) OVER (PARTITION BY t.POL_NO ORDER BY t.UNIQUEKEY)
    END AS "Additions to date TF",
    CASE 
        WHEN t.POL_NO = LAG(t.POL_NO, 1, 0) OVER (ORDER BY t.UNIQUEKEY) THEN 
            ROUND(LAG(#cte."Sum of previous with interest", 1, 0) OVER (ORDER BY t.UNIQUEKEY) * POWER(1 + t.TOTAL_COB_GROWTH / 100, t.DURATION / 12), 0)
        ELSE 
            0
    END AS "Sum of previous with interest",
    #cte.RowNum + 1 AS RowNum
FROM 
    QRYLIB.temp_Test t
JOIN 
    #cte ON t.UNIQUEKEY = #cte.UNIQUEKEY + 1
)
SELECT 
    UNIQUEKEY, 
    POL_NO, 
    NEW_TOTAL_RATE, 
    TOTAL_COB_GROWTH, 
    DURATION,
    "Additions to date TF",
    "Sum of previous with interest"
FROM #cte
WHERE RowNum = 1
ORDER BY UNIQUEKEY;

收到错误:

SQL 错误 [42908]:[SQL0343] 列列表对于表无效。

sql db2 common-table-expression
2个回答
0
投票

您查看错误的详细信息了吗?

原因:

  • 列名列表必须指定在公共表表达式的表名之后。 &1 是公用表表达式名称。
  • 递归普通表的列列表中不能引用序列列名和设置循环列名 表达。 &1 是序列列名称或设置循环列 姓名。对于带有 RENAME 子句的 CREATE INDEX:
  • 键列必须包含在重命名列列表中。

尝试像这样命名列:

WITH #cte (uniquekey, pol_no, new_total_rate,total_cob_growth
           , duration, "Additions to date TF", "Sum of previous with interest"
           , rownum)
 AS (
SELECT 
    UNIQUEKEY, 
    POL_NO, 
    NEW_TOTAL_RATE, 
    TOTAL_COB_GROWTH, 
    DURATION,
    0 AS "Additions to date TF",
    0 AS "Sum of previous with interest",
    1 AS RowNum
FROM 
    QRYLIB.temp_Test
UNION ALL
<..snip...>

0
投票

@Charles,我尝试过仅使用 LAG() 但我无法让它工作,因为两列相互依赖,也许你有解决方案?感觉下面的代码应该可以在 T-SQL 中轻松运行,但 IBM i 不想配合。

SELECT t0.UNIQUEKEY
 , t0.POL_NO
 , t0.NEW_TOTAL_RATE
 , t0.TOTAL_COB_GROWTH
 , t0.DURATION
 , (CASE
    WHEN t0.POL_NO = LAG(t0.POL_NO, 1, 0) OVER (PARTITION BY t0.POL_NO ORDER BY t0.POL_NO)
    THEN CAST(ROUND(LAG(ADDITIONS, 1) OVER (PARTITION BY t0.POL_NO ORDER BY t0.POL_NO),0) --NEED TO LAG ON ADDITIONS
              * POWER((1+(t0."NEW_TOTAL_RATE"/100)),CAST(t0.DURATION AS NUMERIC)/12) AS DECIMAL(20,0))
    ELSE 0
    END) AS PREVIOUS_INTEREST
 , (t0.TOTAL_COB_GROWTH + PREVIOUS_INTEREST) AS ADDITIONS --Column or global variable PREVIOUS_INTEREST not found.
FROM QRYLIB.temp_Test t0
© www.soinside.com 2019 - 2024. All rights reserved.