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

如何在SQL Server递归查询中使用MIN()函数聚合最小日期

在SQL Server递归CTE中从下到上聚合最小日期的实现方法

要实现从树形节点下层向上聚合最小日期,需要调整递归逻辑,从叶子节点开始向上计算,每个父节点的最小日期取自身日期与所有子节点最小日期的最小值。以下是修改后的完整查询:

-- 获取指定树形结构的所有节点(保留原查询的@Top筛选逻辑)
WITH cteP AS
(
    SELECT
        WBS, 
        WBSParent, 
        StartActual, 
        HierID = CONVERT(hierarchyid, CONCAT('/', WBS, '/'))
    FROM
        MSP.MSPMAIN
    WHERE
        ISNULL(@Top,-1) = CASE 
                              WHEN @Top IS NULL 
                                  THEN ISNULL(WBSParent, -1) 
                                  ELSE WBS 
                          END
     
    UNION ALL
    
    SELECT
        r.WBS,
        r.WBSParent,
        r.StartActual,
        CONVERT(hierarchyid, CONCAT(p.HierID.ToString(), r.WBS, '/'))
    FROM
        MSP.MSPMAIN r
    JOIN
        cteP p ON r.WBSParent = p.WBS
),
-- 标记当前树形中的叶子节点(无下属子节点的节点)
cteNodesWithLeaf AS
(
    SELECT
        *,
        IsLeaf = CASE WHEN NOT EXISTS (SELECT 1 FROM cteP c WHERE c.WBSParent = p.WBS) THEN 1 ELSE 0 END
    FROM cteP p
),
-- 从叶子节点向上递归聚合最小日期
cteMinDate AS
(
    -- 锚点:叶子节点的最小日期为自身的StartActual
    SELECT
        WBS,
        WBSParent,
        StartActual,
        HierID,
        MinStartDate = StartActual
    FROM cteNodesWithLeaf
    WHERE IsLeaf = 1

    UNION ALL

    -- 递归:父节点计算自身与子节点的最小日期
    SELECT
        p.WBS,
        p.WBSParent,
        p.StartActual,
        p.HierID,
        MinStartDate = CASE
            WHEN p.StartActual IS NOT NULL THEN MIN(p.StartActual, c.MinStartDate)
            ELSE c.MinStartDate
        END
    FROM cteNodesWithLeaf p
    JOIN cteMinDate c ON p.WBS = c.WBSParent
    WHERE NOT EXISTS (SELECT 1 FROM cteMinDate c2 WHERE c2.WBS = p.WBS)
)
-- 最终输出结果,按层级排序
SELECT
    Lvl = HierID.GetLevel(),
    WBS,
    WBSParent,
    StartActual,
    MinStartDate
FROM cteMinDate
ORDER BY HierID;

逻辑说明

  1. 节点筛选与层级构建:cteP保留原查询的逻辑,获取指定@Top节点下的所有树形节点及层级信息。
  2. 叶子节点标记:cteNodesWithLeaf识别当前树形中的叶子节点(无下属子节点),作为聚合的起点。
  3. 从下到上聚合:cteMinDate递归计算:
    • 叶子节点的最小日期直接取自身的StartActual。
    • 父节点的最小日期取自身StartActual(若不为空)与所有子节点MinStartDate的最小值;若自身日期为空,则直接继承子节点的最小日期。

示例数据验证

针对你提供的示例数据,查询会输出:

  • 节点225117的MinStartDate为2022-10-23,其所有父节点(22511、2251)的MinStartDate也会继承这个值。
  • 节点225216的MinStartDate为2022-08-01,其所有父节点(22521、2252、225)的MinStartDate会取这个最小日期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:15:56