如何基于每行起止时间生成序列并更新SQL表的TimePeriods列?
批量生成时间周期并更新表列需求
我有一张包含Project、ScenarioStart、ScenarioEnd和TimePeriods四列的表,初始时TimePeriods列为空,需要填充每行从ScenarioStart到ScenarioEnd(包含两端)的所有时间周期字符串,格式为yyyyMm,用竖线|分隔。
示例初始数据:
Project ScenarioStart ScenarioEnd TimePeriods 1 2024M9 2025M3 2 2024M6 2024M10
期望更新后结果:
- 第1行
TimePeriods为2024M9|2024M10|2024M11|2024M12|2025M1|2025M2|2025M3 - 第2行
TimePeriods为2024M6|2024M7|2024M8|2024M9|2024M10
现有代码仅支持硬编码起止值,且只生成字符串变量,无法读取表中每行数据并更新对应列,需要改造代码实现批量更新。
改造后的SQL代码
通过游标遍历表中每行数据,调用原逻辑生成时间周期字符串后更新对应行的TimePeriods列:
-- 声明游标,遍历目标表的每行数据 DECLARE project_cursor CURSOR FOR SELECT Project, ScenarioStart, ScenarioEnd FROM YourTableName; -- 替换为你的实际表名 -- 声明变量存储游标取出的每行数据 DECLARE @Project INT, @sScenarioStart NVARCHAR(10), @sScenarioEnd NVARCHAR(10), @SplitPeriods NVARCHAR(MAX) = ''; -- 打开游标 OPEN project_cursor; -- 读取第一行数据到变量 FETCH NEXT FROM project_cursor INTO @Project, @sScenarioStart, @sScenarioEnd; -- 循环处理每行数据 WHILE @@FETCH_STATUS = 0 BEGIN -- 重置时间周期字符串变量 SET @SplitPeriods = ''; -- 初始化计数器变量 DECLARE @sCounterTime NVARCHAR(10) = @sScenarioStart, @sCounterYear NVARCHAR(4) = SUBSTRING(@sScenarioStart, 1, 4), @sCounterMonth NVARCHAR(4) = SUBSTRING(@sScenarioStart, 6, LEN(@sScenarioStart)-5); -- 生成时间周期字符串 WHILE @sCounterTime <> @sScenarioEnd BEGIN SET @SplitPeriods = @SplitPeriods + @sCounterTime + '|'; -- 处理年份和月份的递增逻辑 SET @sCounterYear = CASE @sCounterMonth WHEN 12 THEN CAST(CAST(@sCounterYear AS INT) + 1 AS NVARCHAR(4)) ELSE @sCounterYear END; SET @sCounterMonth = CASE @sCounterMonth WHEN 12 THEN '1' ELSE CAST(CAST(@sCounterMonth AS INT) + 1 AS NVARCHAR(4)) END; SET @sCounterTime = @sCounterYear + 'M' + @sCounterMonth; END -- 添加最后一个周期 SET @SplitPeriods = @SplitPeriods + @sCounterTime; -- 更新当前行的TimePeriods列 UPDATE YourTableName SET TimePeriods = @SplitPeriods WHERE Project = @Project; -- 读取下一行数据 FETCH NEXT FROM project_cursor INTO @Project, @sScenarioStart, @sScenarioEnd; END -- 关闭并释放游标 CLOSE project_cursor; DEALLOCATE project_cursor;
关键改动说明
- 使用游标遍历表中每行数据,替代原硬编码的起止值,实现批量处理
- 在循环中重置
@SplitPeriods变量,避免不同行数据互相干扰 - 修正原代码中年份/月份递增的隐式转换问题(将字符串转为数值计算后再转回字符串)
- 增加
UPDATE语句,将生成的时间周期字符串写入对应行的TimePeriods列
注意:将代码中的YourTableName替换为你实际使用的表名。
内容的提问来源于stack exchange,提问作者CraigA
相关产品推荐
相关产品推荐

