2017-02-21 64 views
-1

我正在寻找一些应该选择“1月份的最后一个星期日”的日期的T-SQL代码。SQL Server的自动接收日期

例如:

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 

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

我这是在SQL Server 2014中使用了一些T-SQL代码:

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) 

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

对于上述日期(2017年1月25日)的回答应该是“2016年1月31日”

+0

无论是日期部分或DATENAME功能将帮助您与此有关。 –

+0

@ dan-bracuk你能否更新T-SQL代码并发送它们?这将是非常有益的。 – user2331670

回答

2

的问题可能是查询是在所提供的一年中找到Jan的第一天,但​​如果Jan是所提供的月份,这将会有所不同。 变化是确定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声明......在这里进行了更改。

+0

感谢工作。我需要另一种方案的另一个T-SQL代码。情景是“为了同样的概念,我希望T-SQL代码选择上一年的日期”。例如1.当前日期是'2017-02-21',那么代码应该选择'2016-01-31'。例如2.当前日期是'2018-02-21',那么代码应该选择'2017-01-29'。请任何帮助。 – user2331670

0

的查找表是解决这种类型的问题的最好方法

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

这个的最右边一列将计算1月前的任何日期的上一个星期日。我已经将其他栏目作为一种简单的方式来记录和实验逻辑。

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

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