【问题标题】:T-SQL autopickup dateT-SQL 自动取件日期
【发布时间】:2017-07-11 01:02:05
【问题描述】:

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

例如:让我们假设,

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

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

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

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

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

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

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

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

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

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

请注意:这是因为年份从一月的最后一个星期日开始

我有以下一些 T-SQL 代码,这些代码在 SQL Server 2014 中使用。它总是选择每年 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 日?

【问题讨论】:

    标签: sql sql-server tsql date


    【解决方案1】:

    您可以使用以下 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

    【讨论】:

    • 所需的输出是一月的最后一个星期日,而不是当前日期的最后一个星期日。
    【解决方案2】:
    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
    

    这对你很有用。

    【讨论】:

    • 感谢它可以正常工作(如果日期在 2 月到 12 月之间)。但是,如果我们将当前日期设置为“2017-01-25”(或一月中的任何其他日期),则结果为空。有什么帮助吗?
    【解决方案3】:

    最右边的列将计算任何日期在一月份的最后一个星期日。我将其他列作为一种简单的方式来记录和试验逻辑。

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

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

    如果您尝试按会计年度分组,请将 PushSampleDatetoFiscalYear 包装在 YEAR() 函数中以输出日期所属的会计年度。要将其用于表格,请将 @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
    

    【讨论】:

      【解决方案4】:

      以下 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 月到 12 月之间,则给出正确答案)。但是,如果我们将当前日期设置为 '2017-01-25'(或 1 月份的任何其他日期),则结果是错误的。对于上述日期(2017-01-25),答案应为“2016-01-31”
      猜你喜欢
      • 2023-03-26
      • 2017-07-12
      • 2015-05-19
      • 1970-01-01
      • 2017-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      相关资源
      最近更新 更多