查找过去两个日历年的先前等效日期

时间:2012-08-15 12:11:49

标签: sql sql-server-2008-r2

如果今天是2012年8月15日,则查询应返回以下内容

15/01/2011,
15/02/2011,
...
...
15/07/2012
15/08/2012

如果今天是2012年8月31日,则查询将返回

31/01/2011,
28/02/2011,  <<<<this is the nearest date
...
...
31/07/2012
31/08/2012

我们的仓库中有一个vw_DimDate应该有帮助

修改 它包含以下字段

enter image description here

目前我正在使用以下内容,但它似乎相当令人费解! ...

DECLARE @Dt DATETIME = '31 JUL 2012'--GETDATE()

;WITH DateSet_cte(DayMarker)
        AS
        (
        SELECT DayMarker
        FROM WHData.dbo.vw_DimDate
        WHERE 
                DayMarker >= CONVERT(DATETIME,CONVERT(CHAR(4),DATEADD(YEAR,-1,@Dt),112) + '0101') AND
                DayMarker <=@Dt
        )
, MaxDate_cte(MaxDate)
        AS
        (
        SELECT [MaxDate] = MAX(DayMarker)
        FROM DateSet_cte 
        )       
SELECT
            [Mth] = CONVERT(DATETIME,CONVERT(CHAR(6),a.DayMarker,112) + '01')
            , MAX(a.DayMarker) [EquivDate]
FROM DateSet_cte a
WHERE DAY(a.DayMarker) <= (SELECT DAY([MaxDate]) FROM MaxDate_cte)
GROUP BY CONVERT(DATETIME,CONVERT(CHAR(6),a.DayMarker,112) + '01')

1 个答案:

答案 0 :(得分:2)

;with Numbers as (
    select distinct number from master..spt_values where number between 0 and 23
), Today as (
    select CONVERT(date,CURRENT_TIMESTAMP) as d
)
select
    DATEADD(month,-number,d)
from
    Numbers,Today
where DATEPART(year,DATEADD(month,-number,d)) >= DATEPART(year,d) - 1

根据我们今年的实际情况,我们希望获得可变数量的返回值似乎很奇怪,但这就是我实施的内容。

当您使用DATEADDmonth添加到某个值时,如果它会产生超出范围的日期(例如2月31日),它会自动调整日期编号,这样就是这个月的最后一天。或者,正如the documentation所说:

  

如果 datepart 日期月的天数多于退货月份和日期天在返回月份中不存在,返回月份的最后一天。

当然,如果您的数据库中已有数字表,则可以取消第一个CTE。你提到你“在我们的仓库中有一个应该有帮助的vw_DimDate”,但由于我对<(大概是一个)视图包含的内容没有没有的想法,所以没有任何帮助。