Question

If I am giving date as 2015-12-31, it must display as

    2015W53, for 2015-12-31, which means Week 53, and next follows as
    2016W1,  Next as
    2016W2,  Next as
    2016W3   Next as...

My logic was

    DECLARE @WEEK VARCHAR(2), @YEAR VARCHAR(4) 
    SELECT @YEAR = DATEPART(YY,@DATE), @WEEK = CAST(DATEPART(WK,@DATE) AS INT) % 52 ; 
     IF(CAST(DATEPART(WK,@DATE) AS INT) % 52 = 0) 
       SET @WEEK = 52; 
     IF(CAST(DATEPART(WK,@DATE) AS INT) = 53) 
       SET @YEAR = CAST(@YEAR AS INT) + 1; 
     IF (LEN(@WEEK) < 2) 
    BEGIN 
      SET @WEEK = LEFT('0' + @week, 2) 
    END 
    RETURN @YEAR + @WEEK

But here 2015W53 is missing and iam getting next 9 weeks,

I just want my last week of the year too.., Tried many times but could not get. Any help is very thankful.

Was it helpful?

Solution

You can concatenate as you want. No need to loop either

SELECT
    YEAR(DATEADD(week, X.Y, BaseDate)),
    DATEPART(ISO_WEEK, DATEADD(week, X.Y, BaseDate))
FROM
    (SELECT CAST('20151231' AS date) AS BaseDate) D
    CROSS JOIN
    (
    VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8)
    ) AS X(Y);

Update SQL Server 2008 added the ISO_WEEK datepart which fixes the week numbering

This almost works because week 2 starts on 03 Jan 2016 according to SQL Server. This is different to ISO week numbering.

OTHER TIPS

@Date is the start date from when you want the week data and @NumberOfWeeks is the number of subsequent weeks for which you want the data. Please modify these values as required.

 --Create the temp table to hold the data
    IF OBJECT_ID('TempDB..#Dates') IS NOT NULL
    DROP TABLE #Dates;

CREATE TABLE #Dates
(   [Year]          INT NOT NULL,
    [WeekNumber]    INT NOT NULL,
    [RequiredWeek]  NVARCHAR(255) NOT NULL,
    [Date]          DATETIME NOT NULL
);


--DECLARE @Date        Datetime='2016-1-1';   --for testing
--DECLARE @Date        Datetime='2016-12-31'; --for testing
DECLARE @Date          Datetime='2015-12-31';
DECLARE @Days          INT;
DECLARE @NumberOfWeeks INT;
DECLARE @Ctr           INT=0;

SET @NumberOfWeeks=9 

WHILE @Ctr<@NumberOfWeeks
BEGIN
    SET @Days=@Ctr*7

    INSERT INTO #Dates
    SELECT  DATEPART(YEAR,@Date+@Days) AS [Year],
            DATEPART(wk,@Date+@Days) AS [WeekNumber],
            CAST(DATEPART(YEAR,@Date+@Days) AS VARCHAR(10))+'W'+ CAST(DATEPART(wk,@Date+@Days) AS VARCHAR(10)) AS [RequiredWeek],
            @Date+@Days AS [Date]
    SET @Ctr=@Ctr+1
END

SELECT * FROM #Dates;

OUTPUT:

Year    WeekNumber  RequiredWeek    Date
2015    53          2015W53          2015-12-31 00:00:00.000
2016    2           2016W2           2016-01-07 00:00:00.000
2016    3           2016W3           2016-01-14 00:00:00.000
2016    4           2016W4           2016-01-21 00:00:00.000
2016    5           2016W5           2016-01-28 00:00:00.000
2016    6           2016W6           2016-02-04 00:00:00.000
2016    7           2016W7           2016-02-11 00:00:00.000
2016    8           2016W8           2016-02-18 00:00:00.000
2016    9           2016W9           2016-02-25 00:00:00.000

To customize it further to your needs and with the risk of making this solution non generic, here is the code which gives 2016W1 after 2015W53 assuming the starting date is '31st DEC 2015'

--Create the temp table
IF OBJECT_ID('TempDB..#Dates') IS NOT NULL
DROP TABLE #Dates;

CREATE TABLE #Dates
(   [Year]          INT NOT NULL,
    [WeekNumber]    INT NOT NULL,
    [RequiredWeek]  NVARCHAR(255) NOT NULL,
    [Date]          DATETIME NOT NULL
);


--DECLARE @Date Datetime='2016-1-1';
--DECLARE @Date Datetime='2016-12-31';
DECLARE @Date Datetime='2015-12-31';
DECLARE @Days INT;
DECLARE @NumberOfWeeks INT;
DECLARE @Ctr INT=0;

SET @NumberOfWeeks=9 

WHILE @Ctr<@NumberOfWeeks
BEGIN
    IF (@Date ='2015-12-31' AND @Ctr=1)  -- To handle 1st week of Jan 2016
    SET @Days=@Ctr+1
    else if (@Date ='2015-12-31' AND @Ctr=0) --To Handle last week of Dec 2015
    SET @Days=(@Ctr)*7
    else
    SET @Days=(@Ctr-1)*7   --for rest of the weeks of 2016

    INSERT INTO #Dates
    SELECT  DATEPART(YEAR,@Date+@Days) AS [Year],
            DATEPART(wk,@Date+@Days) AS [WeekNumber],
            CAST(DATEPART(YEAR,@Date+@Days) AS VARCHAR(10))+'W'+ CAST(DATEPART(wk,@Date+@Days) AS VARCHAR(10)) AS [RequiredWeek],
            @Date+@Days AS [Date]
    SET @Ctr=@Ctr+1
END

SELECT * FROM #Dates;

You may not set @WEEK as DATEPART(WK,@DATE) % 52, as some years have more than 52 weeks! If every year had exactly 52 weeks, things would be easy.

Why don't you just determine the week for the given @DATE and then use DATEADD to add a week and see what comes out? You do this 9 times and you get what you want.

For example:

DECLARE @yearsAndWeeks TABLE (Year INT, Week INT)

DECLARE @i INT
SET @i = 0

DECLARE @Date DATETIME
SET @Date = '20151231'

WHILE @i < 9
BEGIN
    INSERT INTO @yearsAndWeeks (Year, Week) VALUES (DATEPART(yy, @Date), DATEPART(ISO_WEEK, @Date))
    SET @Date = DATEADD(WK, 1, @Date)
    SET @i = @i + 1
END

SELECT * FROM @yearsAndWeeks
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top