user2331670 user2331670 - 1 month ago 8
SQL Question

SQL Server : date automate

Scenario 1: current year

Always SQL code needs to pick The last Sunday of January for the current year. For ex(31-01-2016)

Below SQL code gives answer for above question

select case when DatePart(w, DateAdd(d, 30, DATEADD(y, - DatePart(y, GETDATE()) + 1, convert(date, GetDate())))) = 1
then DateAdd(d, 30, DATEADD(y, - DatePart(y, GETDATE()) + 1, Convert(date, GetDate())))
else DateAdd(d, -DatePart(w, DateAdd(d, 30, DATEADD(y, - DatePart(y, GETDATE()) + 1, GetDate()))) + 1, DateAdd(d, 30, DATEADD(y, - DatePart(y, GETDATE()) + 1, convert(date, GetDate()))))
end


Scenario 2: last year

Always code needs to pick The last Sunday of January for the Previous year. For ex(01-02-2015)

What will be the SQL code Scenario 2 Please?

Week start on Sunday and ends on Saturday.

Answer

Here's a way, using the day of week option (w) for DatePart:

declare @StartDate date = GetDate()
declare @FirstDayofYear date = DATEADD(y, - DatePart(y, @StartDate) + 1, @StartDate)
declare @LastDayOfJanuary date = DateAdd(d, 30, @FirstDayofYear)

select case When DatePart(w, @LastDayofJanuary) = 1
        Then @LastDayofJanuary
        Else DateAdd(d, -DatePart(w, @LastDayOfJanuary) + 1, @LastDayOfJanuary)
    end

Obviously, you can change @StartDate to whatever date you want, including this date last year:

declare @StartDate date = DateAdd(yy, -1, GetDate())

Or, if you want it all expanded into a single expression, here it is with GetDate():

 select case when DatePart(w, DateAdd(d, 30, DATEADD(y, - DatePart(y, GETDATE()) + 1, convert(date, GetDate())))) = 1
        then DateAdd(d, 30, DATEADD(y, - DatePart(y, GETDATE()) + 1, Convert(date, GetDate())))
        else DateAdd(d, -DatePart(w, DateAdd(d, 30, DATEADD(y, - DatePart(y, GETDATE()) + 1, GetDate()))) + 1, DateAdd(d, 30, DATEADD(y, - DatePart(y, GETDATE()) + 1, convert(date, GetDate()))))
    end

Note that this assumes that your machine is set with the week starting on Sunday. You might have to tweak this if you week starts on another day, because day 1 will be a different date.

Edited to add: The formula above will return the last day in January, or the Sunday previous to the last day in January if the last day isn't a Sunday.

But the OP's definition of the last Sunday in January can go into February, based on the example given in the question. Here's a better formula for that situation:

declare @StartDate date = GetDate()
declare @FirstDayofYear date = DATEADD(y, - DatePart(y, @StartDate) + 1, @StartDate)
declare @LastDayOfJanuary date = DateAdd(d, 30, @FirstDayofYear)

select case When DatePart(w, @LastDayofJanuary) = 1
    Then @LastDayofJanuary
    Else DateAdd(d, 7 - DatePart(w, @LastDayOfJanuary) + 1, @LastDayOfJanuary)
end

The expanded version would be:

select case When DatePart(w, DateAdd(d, 30, DATEADD(y, - DatePart(y, GetDate()) + 1, GetDate()))) = 1
    Then DateAdd(d, 30, DATEADD(y, - DatePart(y, GetDate()) + 1, convert(date, GetDate())))
    Else DateAdd(
                d, 
                7 - DatePart(w, DateAdd(d, 30, DATEADD(y, - DatePart(y, GetDate()) + 1, GetDate()))) + 1, 
                DateAdd(d, 30, DATEADD(y, - DatePart(y, GetDate()) + 1, convert(date, GetDate())))
                )
end

TO CONVERT THIS TO RETURN THE PRIOR YEAR'S VALUE

Replace all instances of GetDate() with DateAdd(yy, -1, GetDate()).