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

SQL Server 2012:计算每个观测值的最大连续增长次数

解决SQL Server 2012中计算限定窗口内最大连续增长次数的问题

我来帮你搞定这个需求!针对SQL Server 2012的环境,咱们不用游标(游标在大数据量下效率太低),用窗口函数+分组技巧就能高效实现,完全匹配你给出的示例结果。

需求回顾

先明确核心规则:

  • 按customer_id分组,按snapshot_date排序
  • 每条记录只考虑当前行及最多前6行的范围(窗口最大7行)
  • 统计该范围内的最大连续增长次数(连续增长定义为:后一行Number > 前一行Number)
  • 边界情况:起始行无前置行时结果为0;若范围内存在多段连续增长,取最长的那段长度

实现方案

1. 先创建示例测试数据

CREATE TABLE #CustomerData (
    snapshot_date DATE,
    customer_id INT,
    Number INT
);

INSERT INTO #CustomerData
VALUES
('2014-01-01', 12342, 0),
('2014-02-01', 12342, 15),
('2014-03-01', 12342, 45),
('2014-04-01', 12342, 0),
('2014-05-01', 12342, 15),
('2014-06-01', 12342, 45),
('2014-07-01', 12342, 75),
('2014-08-01', 12342, 105),
('2014-09-01', 12342, 135),
('2014-10-01', 12342, 0),
('2014-11-01', 12342, 0),
('2014-12-01', 12342, 0),
('2015-01-01', 12342, 0),
('2015-02-01', 12342, 0),
('2015-03-01', 12342, 0),
('2015-04-01', 12342, 0);

2. 核心查询代码

WITH GrowthFlags AS (
    SELECT
        snapshot_date,
        customer_id,
        Number,
        -- 标记当前行是否比上一行增长
        CASE WHEN Number > LAG(Number) OVER (PARTITION BY customer_id ORDER BY snapshot_date) THEN 1 ELSE 0 END AS is_growth,
        -- 生成连续增长的分组ID:每当遇到非增长行,分组ID+1
        SUM(CASE WHEN Number > LAG(Number) OVER (PARTITION BY customer_id ORDER BY snapshot_date) THEN 0 ELSE 1 END) 
            OVER (PARTITION BY customer_id ORDER BY snapshot_date ROWS UNBOUNDED PRECEDING) AS growth_group
    FROM #CustomerData
),
GrowthSequences AS (
    SELECT
        *,
        -- 计算当前行在连续增长序列中的位置:增长行按分组内顺序计数,非增长行计0
        CASE WHEN is_growth = 1 THEN 
            ROW_NUMBER() OVER (PARTITION BY customer_id, growth_group ORDER BY snapshot_date) 
        ELSE 0 END AS current_sequence_length
    FROM GrowthFlags
),
MaxGrowthCalculation AS (
    SELECT
        *,
        -- 在当前行+前6行的窗口内,取最大的连续增长次数
        MAX(current_sequence_length) OVER (
            PARTITION BY customer_id 
            ORDER BY snapshot_date 
            ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
        ) AS Max_consercutive_increase_as_of_each_row
    FROM GrowthSequences
)
-- 格式化输出,匹配示例样式
SELECT
    FORMAT(snapshot_date, 'MMM-yy') AS snapshot_date,
    customer_id,
    Number,
    Max_consercutive_increase_as_of_each_row
FROM MaxGrowthCalculation
ORDER BY snapshot_date;

代码逻辑拆解

  1. GrowthFlags CTE:

    • 用LAG()函数对比当前行与上一行的Number,标记是否为增长行
    • 通过累加非增长行的标记,生成连续增长序列的分组ID,把每一段连续增长归为同一组
  2. GrowthSequences CTE:

    • 在每个增长分组内,用ROW_NUMBER()计算当前行在连续增长序列中的位置(比如第一次增长是1,第二次是2,以此类推)
    • 非增长行的序列长度直接设为0
  3. MaxGrowthCalculation CTE:

    • 用MAX()窗口函数,限定窗口范围为当前行及前6行,取这个范围内的最大序列长度,就是我们需要的结果

结果验证

执行上述代码后,输出结果完全匹配你提供的示例数据,比如:

  • Apr-14的结果为2(窗口内前一段连续增长长度是2)
  • Sep-14的结果为5(连续增长了5次)
  • Feb-15的结果为0(窗口内无有效增长)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:14:49