I’m trying to get a table that contains the week number of the last 6 months. I found some code in github, and I modified it to accomplish my goal.
This what I have:
-- choosing date to start with
DECLARE @start_date DATE = DATEADD(MONTH, -6, CURRENT_TIMESTAMP)
SELECT DISTINCT  
    DATEPART(WEEK, DATEADD(DAY, Number, @start_date)) AS week_number, 
    DATEPART(YEAR, DATEADD(DAY, Number, @start_date)) AS year, --adding year number to order by year
    DATEPART(MONTH, DATEADD(DAY, Number, @start_date)) AS month_number
FROM  
    master..spt_values 
WHERE 
    Type = 'P'
    AND DATEADD(DAY, Number, @start_date) <= CURRENT_TIMESTAMP 
    AND DATEPART(YEAR, DATEADD(DAY, Number, @start_date)) > 2019 
— 2019 only used to show the info from 2020 and above, because I don’t want the week number of 2019 or below
I get this result :
The problem is that week 5 is repeated because apparently that week number is between 2 different months, but I just want to keep one of the results no matter the month or year, I want the week number to appear just once.
Is there a way to do this?
Advertisement
Answer
Sure, use GROUP BY in your query and pick either the MAX or MIN value of month_number for each year and week_number.  Here’s an example, but I’m using a recursive CTE rather than that clunky query that relies on a table that has a limited number of numbers in it.
WITH cte AS (
    SELECT
        @start_date AS [date],
        DATEPART(WEEK, @start_date) AS week_number, 
        DATEPART(YEAR, @start_date) AS [year],
        DATEPART(MONTH, @start_date) AS month_number
    UNION ALL
    SELECT
        DATEADD(DAY, 1, [date]) AS [date],
        DATEPART(WEEK, DATEADD(DAY, 1, [date])) AS week_number, 
        DATEPART(YEAR, DATEADD(DAY, 1, [date])) AS [year],
        DATEPART(MONTH, DATEADD(DAY, 1, [date])) AS month_number
    FROM
        cte
    WHERE
        [date] <= GETDATE())
SELECT
    [year],
    MAX(month_number) AS month_number,
    week_number
FROM
    cte
WHERE
    [year] > 2019
GROUP BY
    [year],
    week_number
ORDER BY
    1, 2, 3 OPTION (MAXRECURSION 0);
I get these results:
year month_number week_number 2020 1 1 2020 1 2 2020 1 3 2020 1 4 2020 2 5 2020 2 6 2020 2 7 2020 2 8 2020 2 9 2020 3 10 2020 3 11 2020 3 12 2020 3 13 2020 3 14
If I chose MIN instead of MAX I would get the same results, but week 5 would be assigned to month 1.