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

SQL Server中两个日期范围的n日对应值对比实现问题

问题分析与解决方案

你的核心问题在于关联条件选错了逻辑:原来用DATEADD(day, 1, pre.[date])是按日期的偏移量关联,但需求是两个日期范围内的第n天互相对比(不管两个日期范围的实际日期差多少),所以应该用「行号」来做关联依据,而不是日期本身的偏移。

修正思路

  1. 分别给当期、往期的日期数据按日期升序生成行号,行号就是该日期在对应范围里的「第n天」标识。
  2. 用行号作为关联条件,这样就能保证当期第1天对应往期第1天,第2天对应第2天,以此类推。
  3. 用FULL OUTER JOIN覆盖两个范围长度不一致的情况,再用ISNULL处理缺失值为0或NULL。

修正后的SQL代码

DECLARE @currentStartDateTime datetime = '2018-02-04 00:00:00'
DECLARE @currentEndDateTime datetime = '2018-02-07 23:59:59'
DECLARE @previousStartDateTime datetime = '2018-01-01 00:00:00'
DECLARE @previousEndDateTime datetime = '2018-01-03 23:59:59'

SELECT 
    ISNULL(cur.[date], NULL) AS [curDate],
    ISNULL(cur.[value], 0) AS [curValue],
    ISNULL(pre.[date], NULL) AS [preDate],
    ISNULL(pre.[value], 0) AS [preValue]
FROM (
    -- 给当期日期生成行号,按日期升序排序,行号=第n天
    SELECT 
        [date],
        [value],
        ROW_NUMBER() OVER(ORDER BY [date] ASC) AS day_num
    FROM [data] 
    WHERE [date] BETWEEN @currentStartDateTime AND @currentEndDateTime
) cur
FULL OUTER JOIN (
    -- 给往期日期生成行号,按日期升序排序,行号=第n天
    SELECT 
        [date],
        [value],
        ROW_NUMBER() OVER(ORDER BY [date] ASC) AS day_num
    FROM [data] 
    WHERE [date] BETWEEN @previousStartDateTime AND @previousEndDateTime
) pre
ON cur.day_num = pre.day_num -- 核心:用行号关联,实现第n天对应
ORDER BY ISNULL(cur.day_num, pre.day_num) ASC -- 按行号排序,保证顺序正确

为什么这样能满足需求?

  • 对于示例中的当期4天、往期3天:
    • 当期行号1-4,往期行号1-3
    • 行号1-3关联后,正常显示对应日期和值
    • 行号4时,往期没有对应行,所以preDate为NULL,preValue被ISNULL填充为0,完全符合你给出的期望输出。
  • 当往期比当期长时,当期没有的行号会显示curDate为NULL,curValue为0,同样满足规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:44:42