2017-08-31 144 views
3

我有这个查询,给了我过去15年每一个给定的日期。当我的开始日期是2月29日时,它不会返回2012年,2008年和2004年的29年。我怎样才能让这个查询返回那些年份的29岁?如何保持闰年,减少1年

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 

虽然我想有这样的:只需使用EOMONTH功能(SQL Server 2012中及以上)

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 
+1

而不是从前一个减去一年保持轨道的原始条目日期并使用'i'来减去正确的年数。 –

回答

1

也许使用DateAdd在一个特设的理货台音乐会

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

0

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

+0

如果EntryDate并非总是月末? –

+0

@ lad2025我的例子显示月结束的值,但原始表的日期是一年中的每一天,而不仅仅是月末。 – JulGreen

+0

@JulGreen所以它是** [XY问题](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)**然后。你想创建DimDate表并填充它,一种方法使用添加1:[填充日期维度表](https://stephanefrechette.com/date-dimension/) – lad2025

0

读和写像这样的ite浏览查询......不仅可以处理闰年而不会跳过箍环,它的数量级比现在更高效。

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