Как получить номера следующих 9 недель с текущей даты в SQL?

Если я даю дату 2015-12-31, она должна отображаться как

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

Моя логика была

    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

Но здесь 2015W53 отсутствует, и я получаю следующие 9 недель,

Я просто хочу свою последнюю неделю года тоже.., много раз пытался, но не смог получить. Любая помощь очень благодарна.

4 ответа

Решение

Вы можете объединить, как вы хотите. Нет необходимости в петле

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);

В обновление SQL Server 2008 добавлена ​​часть даты ISO_WEEK, которая фиксирует нумерацию недели

Это почти работает, потому что вторая неделя начинается 3 января 2016 года в соответствии с SQL Server. Это отличается от нумерации недели ISO.

Вы не можете установить @WEEK как DATEPART(WK,@DATE) % 52, так как в некоторые годы есть более 52 недель! Если бы в каждом году было ровно 52 недели, все было бы просто.

Почему бы вам просто не определить неделю для данного @DATE а затем использовать DATEADD добавить неделю и посмотреть, что получится? Вы делаете это 9 раз, и вы получаете то, что вы хотите.

Например:

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

Чтобы настроить его в соответствии с вашими потребностями и с риском сделать это решение не универсальным, вот код, который дает 2016W1 после 2015W53, предполагая, что начальная дата - "31 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;

@Date - это дата начала, когда вам нужны данные недели, а @NumberOfWeeks - количество последующих недель, для которых вы хотите получить данные. Пожалуйста, измените эти значения по мере необходимости.

 --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;

ВЫХОД:

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
Другие вопросы по тегам