sql-server-2008pivotweek-numberdatepart

MSSQL - How to divide each month into 4 weeks?


I have a query that is close to doing what I need:

    select  *
    from
    (
    select      DATEPART (YEAR, order_date) as theYear,
                DATEPART (WEEK, order_date) as theWeek,
                SUM (order_totalPrice) as totalSales
    from        orders_tbl
    where       order_date >= '01/01/2015'
    group by    DATEPART (YEAR, order_date), DATEPART (WEEK, order_date)
    ) as mySourceTable
    pivot
    (
        sum (totalSales)
        for theYear in ([2015], [2016], [2017])
    ) as myPivotTable
    order by theWeek asc

This gives a result like:

    Week    2015    2016    2017
    ----------------------------
    1       $999    $999    $999
    2       $999    $999    $999
    3       $999    $999    $999

But this defines "weeks" as being 7 days starting on a certain day of the week. (I think Monday is the default).

What I really want to do is divide each month into 4 weeks, such that I'll have 48 "weeks" per year, like this:

    Day of Month    Week #
    -----------------------
    1-7             1
    8-14            2
    15-21           3
    22+             4

And my final output would look like:

    Month   Week        2015    2016    2017
    ----------------------------------------
    1       1           $999    $999    $999
    1       2           $999    $999    $999
    1       3           $999    $999    $999
    1       4           $999    $999    $999
    2       1           $999    $999    $999
    2       2           $999    $999    $999

I want to do this because it makes the most business sense for us.

How can I modify the above query to achieve this?

Stipulation 1: This is a query that I am calling from within a web application code (so, I think this rules out some T-SQL stuff... right?) Yes, I could use the web app code to do various loops or other manipulations, but is there a way to do this purely in a single SQL query?

Stipulation 2: I'm using MS SQL 2008 R2.


Solution

  • You can make use if the DAY functions which returns the day of the month.

    DAY(order_date) AS DayOfMonth
    

    Next you can build up your own logic like:

    CASE WHEN DAY(order_date) >= 1 AND DAY(order_date) < 8 THEN 1 
    WHEN DAY(order_date) >= 8 AND DAY(order_date) < 15 THEN 2
    WHEN DAY(order_date) >= 15 AND DAY(order_date) < 22 THEN 3
    ELSE 4 END AS WeekNumber