【问题标题】:Auto pickup dates from SQL Server从 SQL Server 自动取货日期
【发布时间】:2017-07-11 10:43:44
【问题描述】:

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

例如:

Current day      expected result
2017-01-29       2016-01-31
2017-02-05       2017-01-29
2017-02-19       2017-01-29
2018-01-28       2017-01-29
2018-02-04       2018-01-28

这是因为一年从一月的最后一个星期日开始

我有一些 T-SQL 代码正在 SQL Server 2014 中使用:

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

如果当前日期在 2 月到 12 月之间,则上述代码返回正确答案。但是如果我们将当前日期设置为“2017-01-25”(或一月份的任何其他日期),那么结果是错误的。

对于上述日期(2017-01-25),答案应为“2016-01-31”

【问题讨论】:

  • datepart 或 datename 函数都可以帮助您解决这个问题。
  • @dan-bracuk 你能更新 T-SQL 代码并发送它们吗?这将非常有帮助。

标签: sql sql-server sql-server-2008 tsql date


【解决方案1】:

问题可能是查询正在查找所提供年份的一月的第一天,但​​如果一月是所提供的月份,情况就会有所不同。 更改是确定 Jan 是否为提供的月份,并返回去年作为年份。

select 
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7  * 7, '19000107'), 120)

CONVERT(date, CONVERT(VARCHAR(4)...中的CASE 语句是进行更改的地方。

【讨论】:

  • 感谢工作。对于另一个场景,我需要另一个 T-SQL 代码。场景是“对于相同的概念,我希望 T-SQL 代码选择上一年的日期”。例如 1. 当前日期为“2017-02-21”,则代码应选择“2016-01-31”。例如 2. 当前日期为“2018-02-21”,则代码应选择“2017-01-29”。请提供任何帮助。
【解决方案2】:

查找表是解决此类问题的最佳方法

WITH lookup(d) AS
(
  VALUES( ('2016-01-31'),
          ('2017-01-29'),
          ('2018-01-28')
)
select MAX(d)
FROM lookup
WHERE d <= GETDATE()

【讨论】:

    【解决方案3】:

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

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

    DECLARE @Date DATE = '20170205';
    SELECT SampleDate= @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)))) 
    

    要将其用于表格,请将@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
    

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2017-05-17
      • 2020-09-21
      • 2017-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多