Начало предыдущего месяца с воскресенья

#sql #sql-server #tsql

Вопрос:

Я хочу получить начало предыдущего месяца с воскресенья. Например : сегодня 18 июня 2021 года. Я хочу получить дату предыдущего месяца, начиная с воскресенья, т. е. 2 мая 2021 года(выпадает на воскресенье). Я хочу, чтобы он был динамичным, чтобы он проходил в первый день предыдущего месяца, начиная с воскресенья.

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

 select dateadd(mm, -2,dateadd(dd,  1, eomonth(getdate()))) as FirstDayOfPrevMonth
 

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

1. Инвестируйте в таблицу календаря, тогда это тривиально.

2. dateadd(mm, Сколько усилий вы экономите, набирая «мм» вместо «месяц»? Что легче понять?

Ответ №1:

Вы можете достичь этого с помощью EOMONTH, вернувшись на два месяца назад и добавив дни до воскресенья следующего месяца.

 SELECT 
    DATEADD(DAY,8-DATEPART(WEEKDAY,EOMONTH(GETDATE(),-2))
    ,EOMONTH(GETDATE(),-2)) AS FirstSunday_ofThePreviousMonth
 
Первый день_первого месяца
2021-05-02

Примечание: Здесь мы предполагаем, что в воскресенье будет 7 (в соответствии с настройками языка US_English). Дата начала будет 7, для настройки языка US_English. Если это другой языковой параметр, значение вычитания должно быть соответствующим образом изменено.

Ответ №2:

Это куча манипуляций с датами и арифметикой. Но если предположить, что ваши настройки таковы, что «Воскресенье» — это день 1, вы можете использовать:

 select v.*, 
       dateadd(day, (8 - datepart(weekday, v2.prev_month)) % 7, v2.prev_month) as first_sunday_prev_month
from (values (convert(date, '2021-06-18')),
             (convert(date, '2021-09-18')),
             (convert(date, '2021-05-18')),
             (convert(date, '2021-04-18'))
     ) v(dte) cross apply
     (values (dateadd(month, -1, dateadd(day, 1 - day(v.dte), v.dte)) )) v2(prev_month)