Как получить номера следующих 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