Разделить диапазон месяцев по неделям (с понедельника по пятницу) в SQL Server

Я использую SQL Server 2008R2 и пытаюсь разбить заданный месяц на неделю. Я получил следующее решение. Но мне нужны дни между (пн-пт), а не (вс-сб). Как я могу это сделать?

DECLARE @start_date DATETIME, @end_date DATETIME
DECLARE @Table table(StartDate datetime,Enddate datetime,WeekNo int)

SET @start_date = '1 Dec 2018'
SET @end_date =   '31 Dec 2018'

INSERT @Table 
SELECT MIN(dt), MAX(dt), w
FROM
(
    SELECT dt, year(dt) y, DATEPART(week,dt) w
    FROM
    (
        SELECT @start_date + (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1) dt
        FROM sys.columns s1 cross join sys.columns s2
    ) q
    WHERE dt BETWEEN @start_date AND @end_date
) a
group by y,w

Select * from @Table order by startdate, weekno

person 55SK55    schedule 06.12.2018    source источник
comment
Если 1 декабря 2018 года не понедельник, вам нужен понедельник, ближайший к start_date?. и если 31 декабря не пятница, вы хотите, чтобы это была последняя пятница до 31 декабря 2018 года?   -  person George Joseph    schedule 06.12.2018
comment
@ Джордж-Джозеф, если это возможно, это будет здорово. в противном случае регулярные недельные диапазоны также подходят для меня. (т. е. с 31 декабря 2018 г. по 4 января 2019 г.) в случае окончания этого месяца   -  person 55SK55    schedule 06.12.2018
comment
неделя в вашем запросе будет вычисляться на основе самого определения недели iso, не так ли?   -  person George Joseph    schedule 06.12.2018
comment
@ ДжорджДжозеф Да. Как получить обычные недельные диапазоны (например, с 31 декабря 2018 г. по 4 января 2019 г.) в этом случае конца месяца   -  person 55SK55    schedule 06.12.2018


Ответы (1)


Одним из вариантов было бы генерировать только записи и получать даты понедельника между @start_date и @end_date.

После этого убедитесь, что граничные условия учтены для

DECLARE @start_date DATETIME, @end_date DATETIME
DECLARE @Table table(StartDate datetime,Enddate datetime,WeekNo int)

SET @start_date = '1 Nov 2018'
SET @end_date =   '30 Nov 2018'

set datefirst 1;

INSERT @Table 
     SELECT dt as start_of_week
           ,dateadd(dd,4,dt) as end_of_week
           ,DATEPART(week,dt) w
           ,datepart(dw,q.dt)
      FROM
      (
        SELECT @start_date + (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1) dt              
          FROM sys.columns s1 cross join sys.columns s2
       ) q
    WHERE dt BETWEEN @start_date AND @end_date
     AND datepart(dw,q.dt)=1 /*Gets only the days beginning from monday*/
     --AND dateadd(dd,4,q.dt) <= @end_date /*Ignore any records which cross over the @end_date*/

Select * from @Table order by startdate, weekno
person George Joseph    schedule 06.12.2018
comment
Как получить обычные недельные диапазоны (например, с 31 декабря 2018 г. по 4 января 2019 г.) в этом случае конца месяца - person 55SK55; 06.12.2018
comment
Просто избавьтесь от последнего условия -- AND dateadd(dd,4,dt) ‹= @end_date /*Игнорировать любые записи, пересекающие @end_date*/ - person George Joseph; 06.12.2018
comment
Нет, если я это сделаю, это займет пн-вс. Как получить (с 31 декабря 2018 г. по 4 января 2019 г.) - person 55SK55; 06.12.2018
comment
В случае ноября 2018 года он начинается с 5 ноября 2018 года вместо 29 октября (обычная неделя). - person 55SK55; 06.12.2018
comment
Узнал сегодня что-то новое — сначала установите дату. я обновил код, чтобы установить datefirst 1. Теперь вы можете увидеть результаты за 1 ноября 2018 года. - person George Joseph; 06.12.2018