LAG函数是否可以返回一个非NULL的DATE值

时间:2018-10-05 18:50:30

标签: sql-server

我有一个表,其中包含3列[MONTHNAME],[MONTHSTART]和[MONTHEND]。为了进行报告,我需要将之前的所有月份归为一组,但将当前月份按周分组。为此,我需要获取上个月的结束日期。以下是我正在使用的查询,它可以正常运行,但是有没有一种更好的方法来确定上个月的结束日期,而无需创建表或不使用带有LAG函数的CTE?我找不到让LAG函数返回单个值的方法,因此我不得不使用以下内容。我们的月份结束日期不属于日历月份的结束日期,所以我要从自定义日历中提取数据。

DECLARE @tblMonthEndingDates  TABLE
  ([MONTHSTART]   DATE
  ,[MONTHEND]     DATE
  )

INSERT INTO @tblMonthEndingDates
VALUES('01-01-2018', '01-26-2018'),
      ('01-27-2018', '03-02-2018'),
      ('03-03-2018', '03-30-2018'),
      ('03-31-2018', '04-27-2018'),
      ('04-28-2018', '06-01-2018'),
      ('06-02-2018', '06-30-2018'),
      ('07-01-2018', '07-27-2018'),
      ('07-28-2018', '08-31-2018'),
      ('09-01-2018', '09-28-2018'),
      ('09-29-2018', '10-26-2018'),
      ('10-27-2018', '11-30-2018'),
      ('12-01-2018', '12-31-2018')

DECLARE @dtTbl TABLE(RN   INT
                    ,MS   DATE
                    ,ME   DATE
                    );
INSERT INTO @dtTbl
SELECT ROW_NUMBER() OVER(ORDER BY [MONTHSTART]) AS ROWNUM
      ,[MONTHSTART]
      ,[MONTHEND]
FROM @tblMonthEndingDates;

WITH cteDt
AS
(
SELECT d2.[MS]
      ,LAG(d1.[ME]) OVER(ORDER BY d1.[MS]) AS PRIORDT
      ,d2.[ME]
FROM @dtTbl d1
LEFT JOIN @dtTbl d2   ON d1.[RN] = d2.[RN] 
)

SELECT [PRIORDT]
FROM cteDt
WHERE [MS] <= GETDATE() AND [ME] >= GETDATE()

因此,在本月中,我希望将09/28/2018作为查询的返回值,我只想知道是否有更好/更短的方法来返回该值。

3 个答案:

答案 0 :(得分:0)

您可以执行以下操作:

Select 
    Max(MonthEnd) 
From @tblMonthEndingDates 
Where MonthEnd <= GetDate() 

这将为您提供当前日期之前或当天的最新MonthEnd日期。显然,如果您之前确实需要,请使用<而不是<=

答案 1 :(得分:0)

我使用此查询来获取最近@n个月的开始和结束日期。您可以适应您的需求。

declare @t table (SD date,ED date)
declare @i int = 0
 ,@SD date
 ,@ED date
 ,@datetoEval date
 ,@EOM date
 ,@n int = 60

while(@i<=@n)
BEGIN
 set @datetoEval = DATEADD(month,-1*@i,getdate())
 set @SD = cast(cast(month(@datetoEval) as varchar(2)) + '/1/' + cast(year(@datetoEval)  as varchar(4)) as DATE)
 set @ED = dateadd(day,-1,DATEADD(MONTH,1,@SD))

 insert into @t
 values(@SD,@ED)

 set @i=@i+1
END

select * from @t

答案 2 :(得分:0)

我想得太多了。上个月结束了该活动开始的前一天。

JSX