Если вы имели Dates
таблицу, содержащую пять столбцов, FullDate
, Month
, Day
, Year
и DayOfWeek
и заселена с датами в будущем вы могли бы легко сделать следующее.
Предполагая @m
и @y
являются задаваемый пользователем месяц/год катиться вперед, и @d
является дата события:
DECLARE @weekNumInMonth int =
(
SELECT COUNT(1)
FROM Dates
WHERE Year = datepart(year @d)
AND Month = datepart(month, @d)
AND DayOfWeek = datepart(weekday, @d)
AND Day <= datepart(day, @d)
)
SELECT MAX(FullDate)
FROM
(
SELECT TOP @weekNumInMonth
FROM Dates
WHERE Year = @y
AND Month = @m
AND DayOfWeek = datepart(weekday, @d)
) x
Без таблицы дат, вы просто должны сделать некоторые математические:
DECLARE @DOW int = datepart(weekday, @d)
DECLARE @firstDayInMonth date = dateadd(day, 1-datepart(day, @d), @d)
DECLARE @firstDayInMonthDOW int = datepart(weekday, @firstDayInMonth)
DECLARE @firstSameDayInMonth date =
dateadd(day, (7-(@[email protected]))%7, @firstDayInMonth)
DECLARE @weekInMonth int = datediff(week, @firstSameDayInMonth, @d)
DECLARE @corr date = datefromparts(@y, @m, 1)
DECLARE @corrDOW int = datepart(weekday, @corr)
DECLARE @corrFirstSameDay date = dateadd(day, (7-(@[email protected]))%7, @corr)
SELECT dateadd(week, @weekInMonth, @corrFirstSameDay)
SQL Fiddle example
Это немного некрасиво, но то, что он делает:
- Получить первый день месяца, с тем же день недели, как
@d
в @firstSameDayInMonth
.
- Укажите, какая неделя #
@d
находится в пределах соответствующего месяца, как целое число 0 @weekInMonth
. Это число недель между @firstSameDayInMonth
и @d
.
- Получить первый день месяца
@m
, год @y
с таким же днём по неделям как @d
в @corrFirstSameDay
.
- Добавить 0 основываясь на количестве недель
@weekInMonth
на @corrFirstSameDay
, чтобы получить результат.
Вы можете сделать это как однострочный? Конечно, просто замените переменные. Имейте в виду, хотя, это некрасиво, и там действительно ничего можно извлечь из него, за исключением отсутствия читаемости ИМХО:
SELECT dateadd(week, datediff(week, dateadd(day, (7-(datepart(weekday, dateadd(day,
1-datepart(day, @d), @d))-datepart(weekday, @d)))%7, dateadd(day,
1-datepart(day, @d), @d)), @d), dateadd(day, (7-(datepart(weekday,
datefromparts(@y, @m, 1))-datepart(weekday, @d)))%7, datefromparts(@y, @m, 1)))
как вы хотите иметь дело с этим делом: суббота, неделя 5 месяца. Не все месяцы имеют субботу на неделе 5, так что вы хотите использовать субботу недели 4? Я просто замечаю, что вы не идете по неделям, а через какое-то время. так что по-прежнему тот же принцип, не все месяцы имеют 5-ю субботу, так что в таком случае вы хотели бы использовать дату 4-го? – SwissCoder
Нет, дни просто упадут. – user2122092