выбрать эту неделю плюс 7 недель вперед?

У меня есть таблица, которая выглядит так:

введите здесь описание изображения

SELECT
      [Year],
      [Week]
FROM [BI_Planning].[dbo].[tblWeekCalendar]

Я вручную установил рекорды с 1 недели 15 2018 года.

я хотел бы иметь выбор, который дает мне эту неделю (15) + 7 недель вперед, что-то вроде этого:

введите здесь описание изображения

Однако, когда наступит 16-я неделя, у меня должна быть неделя 16 + 7, что будет означать одну новую строку 2018 - 23.

Год должен прийти, чтобы играть здесь еще и потому, что в конце года я хотел бы иметь 2019-1 и так далее.

Чтобы получить неделю, в которой я нахожусь, я использую select datepart(iso_week,getdate())

Это возможно?


person Nils    schedule 09.04.2018    source источник
comment
связанный вопрос stackoverflow. com/questions/37480952/ Как только вы преобразуете номер недели + год в дату, вы можете легко рассчитать диапазон дат и использовать его в предложении WHERE.   -  person Ami Heines    schedule 09.04.2018
comment
Ответ также зависит от того, как вы определяете номер недели, есть несколько способов сделать это.   -  person DavidG    schedule 09.04.2018
comment
Это дает мне неделю в select datepart(iso_week,getdate())   -  person Nils    schedule 09.04.2018
comment
В конце года становится сложно. 30 декабря дает 53-ю неделю в SQL Server. SELECT DATEPART(week, '2018-12-30'). Поскольку в году 52,1429 недель, 30 декабря технически проходит 52-я неделя и начинается 53-я. Считаете ли вы 53-ю неделю действительной?   -  person Zorkolot    schedule 10.04.2018


Ответы (3)


Вместо того, чтобы вставлять вручную или добавлять 7 для расчета номеров недель, вы должны использовать функцию SQL по умолчанию DATEPART, чтобы получить правильный номер недели.

Вы можете генерировать недели в диапазоне дат, как показано ниже.

DECLARE @StartDate DATETIME = '2018-01-01'
DECLARE @EndDate DATETIME = '2019-12-31' 

SELECT DISTINCT  DATEPART( wk, T1.DATE) AS [Week],Year(T1.DATE)
FROM   (
         SELECT
         @StartDate + RN AS DATE 
        FROM   (SELECT ROW_NUMBER() 
                         OVER ( 
                           ORDER BY (SELECT NULL)) RN 
                FROM   master..[spt_values]) T) T1 
WHERE  T1.DATE <= @EndDate 
ORDER BY Year(T1.DATE)

Если вам также нужны WeekStart и WeekEnd, вы можете попробовать следующее.

DECLARE @StartDate DATETIME = '2018-01-01'
DECLARE @EndDate DATETIME = '2019-12-31' 

SELECT MIN(T1.DATE) WeekStart, MAX(T1.DATE) WeekEnd, [Week], [Year]
FROM
(
    SELECT  DATEPART( wk, T1.DATE) AS [Week],Year(T1.DATE) AS [Year], T1.DATE
    FROM   (
            SELECT
            @StartDate + RN AS DATE 
        FROM   (SELECT ROW_NUMBER() 
                            OVER ( 
                            ORDER BY (SELECT NULL)) RN 
                FROM   master..[spt_values]) T) T1 
    WHERE  T1.DATE <= @EndDate 

) T1
GROUP BY [Week], [Year]
ORDER BY [Year],[Week]
person PSK    schedule 09.04.2018
comment
Как я уже сказал в своем комментарии, существует несколько способов расчета номеров недель, здесь показан только один из них. Он также не учитывает, в какой день недели он начинается. - person DavidG; 09.04.2018
comment
День недели в понедельник - person Nils; 09.04.2018
comment
@Nils, что вы имеете в виду под понедельником, вы получаете максимальную и минимальную дату, вы можете легко преобразовать ее в название дня. - person PSK; 09.04.2018

Попробуйте следующий подход

DECLARE @Weekstart int = DATEPART(WW, '2018-01-01')
DECLARE @WeekEnd int = DATEPART(WW, '2018-12-31')

CREATE TABLE #Temp
(
Year int,
WeekNo int
)
INSERT INTO #Temp (Year, WeekNo) VALUES (DATEPART(YYYY, GETDATE()),1)

DECLARE @Count INT
DECLARE @TotalCount INT
SET @TotalCount = DATEPART(WW, '2018-12-31')
SET @Count = 1

WHILE (@Count < @TotalCount)
BEGIN
    DECLARE @WeekNo INT
    SELECT @WeekNo = MAX(ISNULL(WeekNo, 0))+1 FROM #Temp
    INSERT INTO #Temp (Year, WeekNo) VALUES (DATEPART(YYYY, GETDATE()),@WeekNo)
    SET @Count = @Count+1
END

INSERT INTO #Temp (Year, WeekNo) VALUES (DATEPART(YYYY, GETDATE())+1,1)
person Ayyappa.k    schedule 09.04.2018

Вам нужно будет решить, как вы хотите справиться, скажем, с переходом с 2015 на 2016 год. Вы можете использовать такой код, например, чтобы помочь справиться с вашим 7-недельным прогнозом:

DECLARE @start date;
DECLARE @end date;
DECLARE @year int;
DECLARE @week int;

SET @start = '1/1/2015';
SET @end = '12/31/2030';

SET @year = 2016;
SET @week = 50;

WITH cte AS (
SELECT Year(@start) AS Year
    , 1 AS Week
    , @start AS CurDate
    , 1 AS WeekID
UNION ALL
SELECT Year(DATEADD(dd, 7, CurDate))
    , DATEPART(wk, (CASE WHEN DATEPART(dy, DATEADD(dd, 7, CurDate)) <= 7 THEN '1/1/' + CONVERT(varchar, Year(DATEADD(dd, 7, CurDate))) ELSE DATEADD(dd, 7, CurDate) END))
    , (CASE WHEN DATEPART(dy, DATEADD(dd, 7, CurDate)) <= 7 THEN '1/1/' + CONVERT(varchar, Year(DATEADD(dd, 7, CurDate))) ELSE DATEADD(dd, 7, CurDate) END)
    , WeekID + 1
FROM cte
WHERE DATEADD(dd, 7, CurDate) <= @end
)

SELECT Year, Week
FROM cte
WHERE WeekID <= (SELECT x.WeekID FROM cte x WHERE x.Year = @Year AND x.Week = @Week) + 7
AND Year IN (@Year, @Year + 1)
OPTION (maxrecursion 0)

Это предполагает, что вы согласны с «сбросом» на 1 января в начале каждого года — если вы выполняете настоящую 7-дневную прокрутку вперед, вы можете попасть в шаткие сценарии (например, пропустить 1 неделю из некоторых лет, например 2016).

person codexguy    schedule 09.04.2018