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

SQL Server 2016重复T-SQL查询优化:12次日期偏移UNION改写

优化重复UNION的T-SQL查询方案

当然可以!你现在的写法因为重复代码太多,不仅维护起来麻烦,还容易出错。我们可以利用生成月份偏移序列的方式,把12次重复的UNION逻辑压缩成一段简洁的代码,同时保持功能完全一致。

优化后的代码

这里有两种常用的实现方式,都适配SQL Server 2016:

方式一:直接定义固定偏移序列(最直观)

DECLARE @date DATE = '2024-06-01'; -- 替换成你的实际变量

WITH MonthOffsets AS (
    -- 生成0到11的偏移量,对应12个月份的查询逻辑
    SELECT n FROM (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11)) AS nums(n)
)
SELECT z.*
FROM MonthOffsets mo
CROSS APPLY (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [action_timestamp] DESC) AS rowNum,
        [new_state] AS [Last_State],
        DATEADD(MONTH, -mo.n, @date) AS [date]
    FROM [dbo].[CR_hist_Data]
    WHERE [action_timestamp_formatted] < DATEADD(MONTH, -(mo.n + 1), @date)
) z
WHERE z.rowNum = 1;

方式二:递归CTE生成序列(适合动态调整月份数)

如果以后需要增加或减少查询的月份数量,递归CTE的方式会更灵活:

DECLARE @date DATE = '2024-06-01';
DECLARE @monthCount INT = 12; -- 可以直接修改这个值调整月份数

WITH MonthOffsets AS (
    SELECT 0 AS n
    UNION ALL
    SELECT n + 1 FROM MonthOffsets WHERE n < @monthCount - 1
)
SELECT z.*
FROM MonthOffsets mo
CROSS APPLY (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [action_timestamp] DESC) AS rowNum,
        [new_state] AS [Last_State],
        DATEADD(MONTH, -mo.n, @date) AS [date]
    FROM [dbo].[CR_hist_Data]
    WHERE [action_timestamp_formatted] < DATEADD(MONTH, -(mo.n + 1), @date)
) z
WHERE z.rowNum = 1
OPTION (MAXRECURSION 0); -- 如果月份数超过100,必须添加这个选项

优化方案的优势

  • 简洁易维护:核心查询逻辑只写一次,不用重复复制12遍,后续修改条件或月份数时只需调整一处
  • 性能更稳定:SQL Server的查询优化器能更好地处理这种结构化查询,避免重复生成相同的执行计划
  • 扩展性强:如果需要扩展到18个月或缩短到6个月,只需修改序列生成部分的参数即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:13:29