DATEPART WEEK start Monday

  • Hi,

    I'm doing this directly in a computed column:

    case

    when [DUE]<convert([date],getdate(),(0)) then 'OVERDUE'

    when datepart(day,[DUE])=datepart(day,convert([date],getdate(),(0))) AND datepart(month,[DUE])=datepart(month,getdate()) AND datepart(year,[DUE])=datepart(year,getdate()) then 'TODAY'

    when datepart(week,[DUE])=datepart(week,convert([date],getdate(),(0))) AND datepart(month,[DUE])=datepart(month,getdate()) AND datepart(year,[DUE])=datepart(year,getdate()) then 'WEEK'

    when datepart(month,[DUE])=datepart(month,convert([date],getdate(),(0))) AND datepart(year,[DUE])=datepart(year,getdate()) then 'MONTH'

    else 'LATER'

    end

    Only DATEPART with WEEK starts on Sunday, so right now when looking at results today the week ends this coming Saturday, so Sunday's results get given MONTH.

    How can I change WEEK to start with a Monday. As it's in a computed column, I can't use DATEFIRST, nor can I put this in a function with DATEFIRST.

    Thanks

  • lanky_doodle - Monday, August 6, 2018 9:08 AM

    Hi,

    I'm doing this directly in a computed column:

    case

    when [DUE]<convert([date],getdate(),(0)) then 'OVERDUE'

    when datepart(day,[DUE])=datepart(day,convert([date],getdate(),(0))) AND datepart(month,[DUE])=datepart(month,getdate()) AND datepart(year,[DUE])=datepart(year,getdate()) then 'TODAY'

    when datepart(week,[DUE])=datepart(week,convert([date],getdate(),(0))) AND datepart(month,[DUE])=datepart(month,getdate()) AND datepart(year,[DUE])=datepart(year,getdate()) then 'WEEK'

    when datepart(month,[DUE])=datepart(month,convert([date],getdate(),(0))) AND datepart(year,[DUE])=datepart(year,getdate()) then 'MONTH'

    else 'LATER'

    end

    Only DATEPART with WEEK starts on Sunday, so right now when looking at results today the week ends this coming Saturday, so Sunday's results get given MONTH.

    How can I change WEEK to start with a Monday. As it's in a computed column, I can't use DATEFIRST, nor can I put this in a function with DATEFIRST.

    Thanks

    You could actually simplify it taking advantage that the CASE expression actually short circuits when it finds a condition that evaluates to true.

    SELECT CASE
        WHEN x.DUE < CONVERT([DATE], GETDATE(), (0)) THEN 'OVERDUE' --Before today
        WHEN x.Due < DATEADD(DD, DATEDIFF(DD, 0, GETDATE()), 1) THEN 'TODAY' --Before tomorrow
        WHEN x.Due < DATEADD(DD, DATEDIFF(DD, 0, GETDATE()), 7) THEN 'WEEK' --Before next Monday
        WHEN x.Due < DATEADD(MM, DATEDIFF(MM, -1, GETDATE()), 0) THEN 'MONTH' --Before next month
        ELSE 'LATER'
       END
    FROM
    (SELECT c.cal_date AS DUE FROM dbo.Calendar AS c) AS x
    WHERE x.DUE
    BETWEEN GETDATE() - 15 AND GETDATE() + 30;

    Try to understand the formulas taking this into account: the integer values used are converted to dates.

    SELECT n, CAST(n AS DATETIME)
    FROM (VALUES(-1), (0), (1), (7))x(n)

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • Have you considered making use of DATEDIFF(day, DUE, CONVERT(date, GETDATE())) ?

    Steve (aka sgmunson) 🙂 🙂 🙂
    Rent Servers for Income (picks and shovels strategy)

  • depending on your datefirst settings you could try incorporate weekday 
    select datepart(WEEKDAY,getdate())  -- if select @@DATEFIRST = 7 (default) then today would be 2 

    alternatlivly

    look at setting date first to 1???

    set datefirst 1

    ValueFirst day of the week is
    1Monday
    2Tuesday
    3Wednesday
    4Thursday
    5Friday
    6Saturday
    7 (default, U.S. English)Sunday

    ***The first step is always the hardest *******

  • SGT_squeequal - Monday, August 6, 2018 9:51 AM

    depending on your datefirst settings you could try incorporate weekday 
    select datepart(WEEKDAY,getdate())  -- if select @@DATEFIRST = 7 (default) then today would be 2 

    alternatlivly

    look at setting date first to 1???

    set datefirst 1

    ValueFirst day of the week is
    1Monday
    2Tuesday
    3Wednesday
    4Thursday
    5Friday
    6Saturday
    7 (default, U.S. English)Sunday

    This is in a computed column, so DATEFIRST can't be used.

    Steve (aka sgmunson) 🙂 🙂 🙂
    Rent Servers for Income (picks and shovels strategy)

  • Thanks for the tips.

    With Luis' one, that will take the next 7 days. By "this week", I want the calendar week, so when looking at it today, "this week" results should stop on Sunday, NOT 7 days from today, which is what datediff is doing:

    2018-08-08 TODAY Wednesday (correct = today)
    2018-08-09 WEEK - Thursday (correct = week)
    2018-08-10 WEEK - Friday (correct = week)
    2018-08-11 WEEK - Saturday (correct = week)
    2018-08-12 WEEK - Sunday (correct = week)
    2018-08-13 WEEK - Monday (wrong = week, should be month)
    2018-08-14 WEEK - Tuesday (wrong = week, should be month)
    2018-08-15 MONTH - Wednesday (correct = month)

    So I really need week from datepart to be shifted forwards by 1 day (so a week becomes Monday to Sunday and not Sunday to Saturday.)

  • lanky_doodle - Wednesday, August 8, 2018 9:53 AM

    Thanks for the tips.

    With Luis' one, that will take the next 7 days. By "this week", I want the calendar week, so when looking at it today, "this week" results should stop on Sunday, NOT 7 days from today, which is what datediff is doing:

    2018-08-08 TODAY Wednesday (correct = today)
    2018-08-09 WEEK - Thursday (correct = week)
    2018-08-10 WEEK - Friday (correct = week)
    2018-08-11 WEEK - Saturday (correct = week)
    2018-08-12 WEEK - Sunday (correct = week)
    2018-08-13 WEEK - Monday (wrong = week, should be month)
    2018-08-14 WEEK - Tuesday (wrong = week, should be month)
    2018-08-15 MONTH - Wednesday (correct = month)

    So I really need week from datepart to be shifted forwards by 1 day (so a week becomes Monday to Sunday and not Sunday to Saturday.)

    I'm sorry, I forgot one part on the week calculation.

    SELECT CASE
      WHEN x.DUE < CONVERT([DATE], GETDATE(), (0)) THEN 'OVERDUE' --Before today
      WHEN x.Due < DATEADD(DD, DATEDIFF(DD, 0, GETDATE()), 1) THEN 'TODAY' --Before tomorrow
      WHEN x.Due < DATEADD(DD, (DATEDIFF(DD, 0, GETDATE()) / 7)*7, 7) THEN 'WEEK' --Before next Monday
      WHEN x.Due < DATEADD(MM, DATEDIFF(MM, -1, GETDATE()), 0) THEN 'MONTH' --Before next month
      ELSE 'LATER'
     END, x.DUE
    FROM
    (SELECT c.cal_date AS DUE FROM dbo.Calendar AS c) AS x
    WHERE x.DUE
    BETWEEN GETDATE() - 15 AND GETDATE() + 30;

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • That's the ticket, thanks so much 🙂

    Can you break down the calculation for me. I need to add a "next week" group and doing this works, so the last number is the number of days forward (14)?. What's the / 7 ) * 7 bit all about?
    WHEN x.Due < DATEADD(DD, (DATEDIFF(DD, 0, GETDATE()) / 7) * 7, 14) THEN 'WEEK' --Before next, next Monday

  • lanky_doodle - Wednesday, August 8, 2018 11:01 AM

    That's the ticket, thanks so much 🙂

    Can you break down the calculation for me. I need to add a "next week" group and doing this works, so the last number is the number of days forward (14)?. What's the / 7 ) * 7 bit all about?
    WHEN x.Due < DATEADD(DD, (DATEDIFF(DD, 0, GETDATE()) / 7) * 7, 14) THEN 'WEEK' --Before next, next Monday

    That's right, you would need to use 14.
    The /7*7 is basically taking advantage of  integer divisions to get complete weeks from a certain day. 1900-01-01 (date zero) is a Monday, so we have 6188 weeks and 2 days since then. Integer division would just return 6188 instead of 6188.285714. We then add the weeks as days and that's why we need to multiply by seven again. We could also add weeks directly and it might become clearer.

      WHEN x.Due < DATEADD(WK, (DATEDIFF(DD, 0, GETDATE()) / 7) + 1, 0) THEN 'WEEK' --Before next Monday
      WHEN x.Due < DATEADD(WK, (DATEDIFF(DD, 0, GETDATE()) / 7) + 2, 0) THEN 'NEXT WEEK' --Before next, next Monday

    EDIT: If you need to change the start of the week, replace 0 with other numbers from 1 to 6 depending on the day you want (It works with others but I prefer to keep it simple).

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • By the way, what would happen in dates like 2018-08-29? Would you have no rows for month?

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • Thanks.

    Yes, on dates right at the end of a month that's what I expect. I've changed the label from 'This month' the 'Later this month' to make it clearer.

Viewing 11 posts - 1 through 10 (of 10 total)

You must be logged in to reply to this topic. Login to reply