如何在减去1年时保持闰年

时间:2017-08-31 18:03:47

标签: sql sql-server tsql

我有这个查询给了我过去15年中每一年的特定日期。当我的开始日期是2月29日时,它不会返回2012年,2008年和2004年的29年。如何让这个查询返回那些年份的29?

DECLARE @TempDate1 TABLE (Entry_Date Date)
INSERT INTO @TempDate1 values ('2016-02-29')
;WITH
      a AS(SELECT DATEADD(yy,-1,Entry_Date) d,  DATEADD(yy,-1,Entry_Date) d2,0  i
        FROM @TempDate1 
          UNION all
        SELECT DATEADD(yy,-1,d),DATEADD(yy,-1,d2),i+1 FROM a WHERE i<14),
      b AS(SELECT d,d2, DATEDIFF(dd,0,d)%7 dd,i FROM a)
 SELECT 
 d AS Entry_Date
 FROM b

它返回:

Entry_Date
2015-02-28
2014-02-28
2013-02-28
2012-02-28
2011-02-28
2010-02-28
2009-02-28
2008-02-28
2007-02-28
2006-02-28
2005-02-28
2004-02-28
2003-02-28
2002-02-28
2001-02-28

虽然我想这样:

Entry_Date
2015-02-28
2014-02-28
2013-02-28
2012-02-29
2011-02-28
2010-02-28
2009-02-28
2008-02-29
2007-02-28
2006-02-28
2005-02-28
2004-02-29
2003-02-28
2002-02-28
2001-02-28

3 个答案:

答案 0 :(得分:1)

也许DateAdd与ad-hoc计数表一致

示例

Declare @YourTable Table ([Entry_Date] date)
Insert Into @YourTable Values 
 ('2016-02-29')
,('2015-07-22')

Select YearNr = N
      ,Anniv  = dateadd(YEAR,N*-1,Entry_Date) 
 From  @YourTable A
 Cross Apply (
                Select Top 15 N=Row_Number() Over (Order By (Select NULL)) From master..spt_values n1
             ) B

<强>返回

enter image description here

答案 1 :(得分:0)

只需使用EOMONTH函数(SQL Server 2012及更高版本):

DECLARE @TempDate1 TABLE (Entry_Date Date)
INSERT INTO @TempDate1 values ('2016-02-29')
;WITH
      a AS(SELECT DATEADD(yy,-1,Entry_Date) d,  DATEADD(yy,-1,Entry_Date) d2,0  i
        FROM @TempDate1 
          UNION all
        SELECT DATEADD(yy,-1,d),DATEADD(yy,-1,d2),i+1 FROM a WHERE i<14),
      b AS(SELECT d,d2, DATEDIFF(dd,0,d)%7 dd,i FROM a)
 SELECT EOMONTH(d) AS Entry_Date
 FROM b;

<强> Rextester Demo

答案 2 :(得分:0)

像这样重写巡演查询......不仅可以在没有跳过篮球的情况下处理闰年,它的效率也会比你现在提高几个数量级。

 DECLARE @BaseDate DATE = '2016-02-29';

 SELECT 
    Entry_Date = DATEADD(YEAR, t.n, @BaseDate)
 FROM 
    (VALUES (-1),(-2),(-3),(-4),(-5),
            (-6),(-7),(-8),(-9),(-10),
            (-11),(-12),(-13),(-14),(-15) ) t (n);

结果...

Entry_Date
----------
2015-02-28
2014-02-28
2013-02-28
2012-02-29
2011-02-28
2010-02-28
2009-02-28
2008-02-29
2007-02-28
2006-02-28
2005-02-28
2004-02-29
2003-02-28
2002-02-28
2001-02-28

编辑:与日期表一起使用时的功能相同(我偷走了约翰的桌子)

DECLARE @YourTable TABLE (id INT, Entry_Date DATE);
INSERT INTO @YourTable VALUES (1, '2016-02-29'), (2, '2015-07-22');

 SELECT 
    yt.id,
    Entry_Date = DATEADD(YEAR, t.n, yt.Entry_Date)
 FROM 
    @YourTable yt
    CROSS APPLY (VALUES (-1),(-2),(-3),(-4),(-5),
                        (-6),(-7),(-8),(-9),(-10),
                        (-11),(-12),(-13),(-14),(-15) ) t (n);
GO

结果...

id          Entry_Date
----------- ----------
1           2015-02-28
1           2014-02-28
1           2013-02-28
1           2012-02-29
1           2011-02-28
1           2010-02-28
1           2009-02-28
1           2008-02-29
1           2007-02-28
1           2006-02-28
1           2005-02-28
1           2004-02-29
1           2003-02-28
1           2002-02-28
1           2001-02-28
2           2014-07-22
2           2013-07-22
2           2012-07-22
2           2011-07-22
2           2010-07-22
2           2009-07-22
2           2008-07-22
2           2007-07-22
2           2006-07-22
2           2005-07-22
2           2004-07-22
2           2003-07-22
2           2002-07-22
2           2001-07-22
2           2000-07-22