T-SQL autopickup日期

时间:2017-02-21 12:01:03

标签: sql sql-server tsql date

我正在寻找一些T-SQL代码,它应该选择一月份的最后一个星期日"

例如: 让我们假设,

Senario 1:当前日期为 - ' 2017-01-29'

  • 代码应该选择 - ' 2016-01-31'

Senario 2:当前日期为 - ' 2017-02-05'

  • 代码应该选择 - ' 2017-01-29'

Senario 3:当前日期为 - ' 2017-02-19'

  • 代码应该选择 - ' 2017-01-29'

Senario 4:当前日期为 - ' 2018-01-28'

  • 代码应该选择 - ' 2017-01-29'

Senario 5:当前日期为 - ' 2018-02-04'

  • 代码应该选择 - ' 2018-01-28'

请注意: 这是因为年份从1月份的上周日开始

我有一些在SQL Server 2014中使用的T-SQL代码。它总是选择每年的1月31日 - 这是错误的。

select CASE 
    WHEN    GETDATE() <= DATEADD(Day,-0,CONVERT(datetime, CONVERT(varchar(4), (year(GETDATE()))) + '-02-01'))
    THEN    DATEADD(Day,-1,CONVERT(datetime, CONVERT(varchar(4), (year(GETDATE())-1)) + '-02-01'))
    ELSE    DATEADD(Day,-1,CONVERT(datetime, CONVERT(varchar(4), (year(GETDATE()))) + '-02-01'))
END 

为什么总是选择1月31日?

4 个答案:

答案 0 :(得分:0)

您可以使用以下SQL查询来获取给定日期的最后日期

DECLARE @dtDate DATETIME
SET @dtDate = '2/21/2017'

SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@dtDate)+1,0))

输出:2017-02-28 23:59:59.000

SELECT FORMAT(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@dtDate)+1,0)), 'yyyy-MM-dd') AS LastDate

输出:2017-02-28

答案 1 :(得分:0)

以下T-SQL为您提供所需的结果。

Declare @dtMyDate datetime

select @dtMyDate = '2017-01-25'

select case 
        when datepart(month,@dtMyDate) = 1

        then convert(varchar(10), DATEADD(day,DATEDIFF(day,'19000107',
        DATEADD(month,DATEDIFF(MONTH,0, 
        CONVERT(date, CONVERT(VARCHAR(4), dateadd(year,-1,@dtMyDate), 112)+'0101')),30))/7*7,'19000107'), 120)

        else convert(varchar(10), DATEADD(day,DATEDIFF(day,'19000107',
        DATEADD(month,DATEDIFF(MONTH,0, 
        CONVERT(date, CONVERT(VARCHAR(4), @dtMyDate, 112)+'0101')),30))/7*7,'19000107'), 120)
        end

<强>结果: -

2016-01-31

帮助我的参考资料: -

how to extract current year and combine with specific month and date as a date

Find Last Sunday

答案 2 :(得分:0)

DECLARE @LastJanuarySunday DATE = CONVERT(DATE,CAST((SELECT DATEPART(YEAR, GETDATE())) AS VARCHAR(4)) + '-01-01')
DECLARE @LastDay DATE = 
(SELECT DATEADD(dd,-(DATEPART(WEEKday, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,convert(datetime,@LastJanuarySunday,112))+1,0)))-1),DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,convert(datetime,@LastJanuarySunday,112))+1,0))))
DECLARE @InputDate DATE = GETDATE()


SELECT CASE WHEN @InputDate > @LastDay AND @LastJanuarySunday <> @LastDay
   THEN @LastDay
   WHEN @InputDate = @LastDay
   THEN DATEADD(DAY, 2, @LastDay)
   END

这对您有用。

答案 3 :(得分:0)

最右边一列将计算任何日期1月份的上一个星期日。我已经将其他列留下来作为记录和试验逻辑的简单方法。

没有分支逻辑,它都是纯日期数学,所以它应该合理地快速聚合,并且应该能够在日期列上使用索引。

DECLARE @Date DATE = '20170205';
SELECT SampleDate= @Date  ,
    EndOfSampleMonth = EOMONTH(@Date) ,
    SampleMonthNumber = DATEPART(MONTH,@Date) ,
    MostRecentJanuaryForSampleMonth = DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date) ,
    LastDayOfMostRecentJanuary = EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)) ,
    WeekDayOfLastDayOfMostRecentJanuary = DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date))) ,
    LastSundayOfJanuary = DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date))) ,
    LastSundayOfJanuaryDayOfYear= DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))) ,
    PushSampleDateToFiscalYear = DATEADD(DAY,(DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date))))) * -1 ,@date) ,
    PreviousLastSundayInJanuaryForSampleDate = DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH
,DATEADD(DAY,((DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))))-1) * -1 ,@Date))-1)*-1
,DATEADD(DAY,((DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))))-1) * -1 ,@Date))))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH
,DATEADD(DAY,((DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))))-1) * -1 ,@Date))-1)*-1
,DATEADD(DAY,((DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))))-1) * -1 ,@Date)))) 

如果您尝试按会计年度进行分组,请在YEAR()函数中包装PushSampleDatetoFiscalYear,以输出该日期所属的会计年度。要对表使用它,请将@Date替换为您自己的日期字段。

更新了样本结果:

SampleDate  PreviousLastSundayInJanuaryForSampleDate
2008-06-03  2008-01-27
2008-12-20  2008-01-27
2009-07-08  2009-01-25
2010-01-24  2009-01-25
2010-08-12  2010-01-31
2011-02-28  2011-01-30
2011-09-16  2011-01-30
2012-04-03  2012-01-29
2012-10-20  2012-01-29
2013-05-08  2013-01-27
2013-11-24  2013-01-27
2014-06-12  2014-01-26
2014-12-29  2014-01-26
2015-07-17  2015-01-25
2016-02-02  2016-01-31
2016-08-20  2016-01-31
2017-03-08  2017-01-29
2017-09-24  2017-01-29
2018-04-12  2018-01-28
2018-10-29  2018-01-28
2019-05-17  2019-01-27
2019-12-03  2019-01-27
2020-06-20  2020-01-26