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

如何在SQL Server的CASE WHEN语句中递增局部变量?

在SQL Server中基于错误场景生成分组ID的正确实现

原代码的问题

你之前的写法存在两个核心问题:

  1. 语法错误:SQL Server不允许在SELECT语句中同时给局部变量赋值并将其作为结果列返回,这会直接触发语法报错。
  2. 逻辑不可靠:即使绕过语法问题,依赖局部变量逐行递增的方式也无法保证结果正确——SQL Server不承诺SELECT语句的执行顺序和输出顺序一致,变量的累加结果可能完全不符合预期。

正确解决方案:用窗口函数实现分组ID

要实现按指定错误场景递增分组ID的需求,推荐使用SUM() OVER()窗口函数来累计分组触发条件,这是SQL Server中生成这类分组的标准、可靠方法。

完整代码示例

WITH CTE_Movements AS (
    SELECT 
        a.CPUT AS Tim,
        a.USNA AS wayq,
        a.WE AS Pl,
        a.MA AS Mau,
        b.MAK AS Material_Desc,
        a.BW AS Movement_type,
        c.BTE AS Movement_Type_Text,
        LAG(a.BW) OVER (ORDER BY a.MB, a.ZE) AS Prev_Movement_type,
        -- 标记当前行是否需要开启新分组
        CASE 
            WHEN (a.BW IN ('13', '16') AND LAG(a.BW) OVER (ORDER BY a.MB, a.ZE) IN ('14', '15'))
            THEN 1
            ELSE 0
        END AS Is_New_Group,
        a.MB,
        a.ZE
    FROM Database_Table3 a 
    LEFT JOIN Database_Table4 b ON a.MA = b.MA
    LEFT JOIN Database_Table5 c ON a.BW = c.BW
    WHERE a.BW IN ('13', '14', '15', '16')
)
SELECT 
    Tim,
    wayq,
    Pl,
    Mau,
    Material_Desc,
    Movement_type,
    Movement_Type_Text,
    Prev_Movement_type,
    -- 累计新分组标记,生成连续的GroupID
    SUM(Is_New_Group) OVER (ORDER BY MB, ZE ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + 1 AS GroupID
FROM CTE_Movements
ORDER BY MB, ZE;

代码说明

  1. CTE预处理:先通过公共表表达式(CTE)筛选数据,计算每行的Prev_Movement_type,并标记Is_New_Group——当满足你定义的错误场景(当前移动类型是13/16且上一行是14/15)时,标记为1,否则为0。
  2. 生成GroupID:在主查询中,用SUM(Is_New_Group) OVER(...)累计从第一行到当前行的所有新分组标记值,再加上初始值1,就能得到连续递增的分组ID。每遇到一个错误场景,GroupID自动加1。

扩展说明

如果需要按MB字段进行独立分组(即每个MB内部单独生成GroupID),只需修改窗口函数的OVER子句,添加PARTITION BY MB:

SUM(Is_New_Group) OVER (PARTITION BY MB ORDER BY ZE ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + 1 AS GroupID

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:06:31