SQL中计算上一年度首尾日期的逻辑解析咨询
解析计算上一年度首尾日期的SQL逻辑
先看你贴的SQL代码:
DECLARE @FromTestDate Datetime DECLARE @ToTestDate Datetime DECLARE @FromDate DATETIME DECLARE @ToDate DATETIME SET @FromTestDate= DATEDIFF(yy,0,GETDATE()) SELECT @FromTestDate AS FromTestDate SET @FromDate = DATEADD(yy, datediff(yy, 0, GETDATE())-1, 0) --@FromDate should be (CurrentDate + From TestDate -- 3800-06-04) SELECT @FromDate As FromDate SET @ToTestDate= DATEDIFF(yy,30,GETDATE()) SELECT @ToTestDate AS ToTestDate SET @ToDate = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), -1) SELECT @ToDate AS ToDate
你误解的核心是把DATEDIFF的结果当成了日期值,但实际上它返回的是两个日期之间的间隔数,DATEADD的第二个参数也是间隔数,不是日期,下面拆解每部分逻辑:
1. 先搞懂DATEDIFF(yy, 0, GETDATE())的含义
在SQL Server里,数字0会被自动转换为日期1900-01-01(这是SQL的默认基准日期)。DATEDIFF(yy, 0, GETDATE())的作用是计算当前日期和1900-01-01之间的年份差,比如当前是2025年,结果就是2025-1900=125——它是一个整数,不是日期。你看到的3800-06-04是把这个整数强行存为Datetime类型后,SQL自动转换出的日期(本质是1900-01-01加对应天数),属于类型误解导致的混乱。
2. 计算上一年度第一天:@FromDate
SET @FromDate = DATEADD(yy, datediff(yy, 0, GETDATE())-1, 0)
拆解逻辑:
datediff(yy, 0, GETDATE())得到当前年份与1900年的差值,比如125(对应2025年)- 减1后得到
124,也就是上一年(2024年)与1900年的差值 DATEADD(yy, 124, 0)就是在基准日期1900-01-01的基础上加124年,结果就是2024-01-01,也就是上一年的第一天。
3. 计算上一年度最后一天:@ToDate
SET @ToDate = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), -1)
这里的-1会被转成日期1899-12-31(即基准日期减1天):
datediff(yy, 0, GETDATE())还是当前年份与1900年的差值125DATEADD(yy,125,1899-12-31)就是给1899-12-31加125年,结果是2024-12-31,也就是上一年的最后一天。
4. 关于多余的@FromTestDate和@ToTestDate
这两个变量属于调试残留的测试代码:
@FromTestDate把年份差的整数存为Datetime类型,导致显示出奇怪的日期,和最终计算无关@ToTestDate用30转成1900-01-30计算年份差,同样不参与@ToDate的逻辑
总结核心思路:利用SQL默认基准日期1900-01-01,通过DATEDIFF算出当前年份与基准年的差值,再用DATEADD在基准日期(或基准日期减1天)上叠加对应差值,快速定位到目标年份的首尾日期。
内容的提问来源于stack exchange,提问作者Saran
相关产品推荐
相关产品推荐

