Получение недельного периода на основе номера недели, месяца и года sql

#sql #tsql

#sql #tsql

Вопрос:

Мне нужно получить первый и последний день недели на основе номера недели, года и месяца

Моя неделя начинается в субботу и заканчивается в пятницу Пример: Год: 2020 Неделя: 45

Обычный период недели: Первый день: 2020-10-31 ~ Последний день: 2020-11-06

Мне нужно вернуть что-то вроде

Октябрь: Первый день: 2020-10-31 ~ последний день: 2020-10-31

Ноябрь: первый день 2020-11-01 ~ последний день: 2020-11-06

мой запрос для возврата последнего дня недели:

 select DATEADD (WEEK, @PcpSemana, DATEADD (YEAR,  ('20'   LEFT(@PcpPeriodo,2))-1900, 0)) - 5 as lastDayOfWeek 
 

мой запрос для возврата первого дня недели

 SELECT WeekStart = DATEADD(DAY, 
                        (CEILING(DATEPART(DAY, DATEADD (WEEK, @PcpSemana, DATEADD (YEAR,  ('20'   LEFT(@PcpPeriodo,2))-1900, 0)) - 5) / 7.0) - 1) * 7,
                        DATEADD(MONTH, DATEDIFF(MONTH, 0,DATEADD (WEEK, @PcpSemana, DATEADD (YEAR,  ('20'   LEFT(@PcpPeriodo,2))-1900, 0)) - 5), 0));
 

Я использую SET DATEFIRST 6
Я не могу сильно развиваться

PcpPeriodo содержит YYMM (2011) = 2020 / 11 ) PcpSemana содержит weeknumber (45) (01 ~ 53)

Комментарии:

1. Почему ваш первый пример начинается и заканчивается в один и тот же день? Если у вас нечетные нумерации недель, вы, вероятно, захотите создать таблицу календаря.

Ответ №1:

Я не уверен, как выглядят ваши данные, но если у вас есть первый день недели, вы можете разделить его на месяцы следующим образом:

 select weeks.*
from (values (convert(date, '2020-10-31'))) w(weekstart) cross apply
     (values (dateadd(day, 6, w.weekstart), eomonth(w.weekstart))
     ) v(weekend, eom) cross apply
     (values (w.weekstart,
              case when v1.weekend <= v1.eom then v1.weekend else v1.eom end
             ),
             (case when v1.weekend > v1.eom then dateadd(day, 1, v1.eom) end,
              case when v1.weekend > 1.eom then v1.weekend
             )
      ) weeks(weekstart, weekend)
where weeks.weekstart is not null;
 

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

Ответ №2:

 DECLARE @d datetime;

SET DATEFIRST 6;
SET @d = '2020-11-01';

WITH weektest as (
  select @d as d
  union all
  select DATEADD(DAY,1,d) from weektest where d<='2020-11-6'
)
SELECT 
   d, 
   DATEPART(week, d), 
   DATEPART(weekday,d),
   DATENAME(weekday,d)
from weektest;
 

выходной сигнал:

 d                                               
----------------------- ----------- ----------- ------------------------------
2020-11-01 00:00:00.000 45          2           Sunday
2020-11-02 00:00:00.000 45          3           Monday
2020-11-03 00:00:00.000 45          4           Tuesday
2020-11-04 00:00:00.000 45          5           Wednesday
2020-11-05 00:00:00.000 45          6           Thursday
2020-11-06 00:00:00.000 45          7           Friday
2020-11-07 00:00:00.000 46          1           Saturday