1

如果今天是 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 应该会有所帮助

编辑 它包含以下字段

在此处输入图像描述

目前我正在使用以下内容,但看起来相当复杂!...

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')
4

1 回答 1

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

根据我们一年中的距离,想要可变数量的返回值似乎很奇怪,但这就是我已经实现的。

当您使用DATEADDmonths 添加到一个值时,如果它会产生一个超出范围的日期(例如 2 月 31 日),它会自动调整天数,使其成为该月的最后一天。或者,正如文档所说:

如果datepart月份,并且日期月份的天数比返回月份的天数多,并且返回月份中不存在日期日期,则返回返回月份的最后一天。

当然,如果您的数据库中已经有一个 numbers 表,您可以消除第一个 CTE。您提到您“我们的仓库中有一个 vw_DimDate 应该会有所帮助”,但是由于我知道那个(大概是一个)视图包含什么,所以它没有任何帮助。

于 2012-08-15T12:16:59.673 回答