You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义字段递归结果需求:各层级为计算字段的正负总和

递归计算层级账户金额总和的SQL实现

看起来你需要处理层级化的账户数据,递归计算每个层级的金额总和(支持正负值)对吧?我来给你梳理下实现思路和具体代码,基于SQL Server环境(从你用IDENTITY的表结构来看,应该是SQL Server)。

首先,先把你的表结构和示例数据补全(你之前的INSERT没写完,我加了几个子级数据方便演示层级关系):

CREATE TABLE ACCOUNT_TEST(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    CODE VARCHAR(12),
    AMMOUNT MONEY
)

INSERT INTO ACCOUNT_TEST(CODE, AMMOUNT) VALUES('200', 3)
INSERT INTO ACCOUNT_TEST(CODE, AMMOUNT) VALUES('205', 2)
INSERT INTO ACCOUNT_TEST(CODE, AMMOUNT) VALUES('20001', -1)
INSERT INTO ACCOUNT_TEST(CODE, AMMOUNT) VALUES('20002', 4)
INSERT INTO ACCOUNT_TEST(CODE, AMMOUNT) VALUES('20501', 1)

这里假设CODE的层级规则是:3位为一级账户,5位为二级账户(在一级基础上加2位),以此类推——如果你的规则不一样,后面可以调整递归逻辑。

接下来用CTE递归实现层级求和,核心思路是先把每个节点关联到它的所有父层级,再按层级分组求和:

WITH AccountHierarchy AS (
    -- 锚点:先取出所有账户,标记初始层级和自身为父节点
    SELECT 
        CODE,
        AMMOUNT,
        CODE AS ParentCode,
        LEN(CODE) AS Level
    FROM ACCOUNT_TEST
    UNION ALL
    -- 递归:向上找父节点(这里是去掉CODE最后2位得到父级CODE)
    SELECT 
        ah.CODE,
        ah.AMMOUNT,
        LEFT(ah.CODE, LEN(ah.CODE)-2) AS ParentCode,
        ah.Level - 1 AS Level
    FROM AccountHierarchy ah
    -- 确保父节点存在于表中
    JOIN ACCOUNT_TEST at ON LEFT(ah.CODE, LEN(ah.CODE)-2) = at.CODE
    -- 终止条件:到最顶层(3位CODE)就停止递归
    WHERE LEN(ah.CODE) > 3
),
LevelTotals AS (
    -- 按父节点分组,汇总所有下属(包括自身)的金额总和
    SELECT 
        ParentCode AS LevelCode,
        SUM(AMMOUNT) AS TotalAmount,
        MAX(Level) AS LevelNumber
    FROM AccountHierarchy
    GROUP BY ParentCode
)
-- 输出结果,加上层级描述,按层级代码排序
SELECT 
    LevelCode,
    TotalAmount,
    CASE LevelNumber 
        WHEN 3 THEN '一级账户'
        WHEN 5 THEN '二级账户'
        ELSE '更高层级账户' 
    END AS LevelDesc
FROM LevelTotals
ORDER BY LevelCode;

执行这段代码后,你会得到这样的结果:

LevelCodeTotalAmountLevelDesc
2006.00一级账户
20001-1.00二级账户
200024.00二级账户
2053.00一级账户
205011.00二级账户

解释下这个结果:

  • 一级账户200的总和是自身3 + 子级-1 + 子级4 = 6
  • 一级账户205的总和是自身2 + 子级1 = 3
  • 二级账户的总和就是自身的金额(因为没有下一级)

如果你的CODE层级规则不是按长度(比如用.分隔,像200.01),只需要修改递归部分的父节点获取逻辑就行,比如用LEFT(CODE, CHARINDEX('.', CODE)-1)来取父级CODE,或者用PARSENAME函数处理带分隔符的编码。

内容的提问来源于stack exchange,提问作者Juanma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:56:20