2013-03-01 4 views
1

이벤트를 생성하는 일정 관리 시스템을 개발 중입니다. 나는 모든 이벤트 (하루에 발생)를 사용자가 지정한 월/연도로 "롤 포워드"할 수 있어야합니다.해당 요일을 기준으로 향후 날짜를 어떻게 찾을 수 있습니까?

예를 들어, 2013 년 3 월 4 일은 월요일입니다. 주어진 달/년에 해당하는 날짜가 평일과 그 달의 위치를 ​​기준으로 결정될 수 있어야합니다. 따라서이 예에서 4 월에 해당하는 날짜는 4 월 1 일이며 이는 월요일입니다.

또 다른 예 : 그것은 사용자가 제공 한 월/년이 변수라는 사실이 없었다면 월에 해당 날짜가 월 8

될 수 있도록 2013년 3월 13일는 수요일,이되지 않을 것입니다 그렇게 어려운 일; 이 때문에 당신이 아니라 미래에 Dates 다섯 개의 열, FullDate, Month, Day, YearDayOfWeek을 포함하는 테이블 및 날짜로 채워이 있다면하지만 ...

+0

어떻게이 사건을 처리 할 할 : 토요일, 주 5 월. 모든 달에는 주 5의 토요일이있는 것은 아닙니다. 그래서 4 주째의 토요일을 사용하고 싶습니까? 나는 단지주의를 기울인다. 당신은 몇 주 지나지 않고 하루 만에 출현한다. 그래서 여전히 같은 원칙, 모든 달이 5 번째 토요일을 갖는 것은 아니기 때문에, 대신에 4 번째 날짜를 사용하고 싶습니다. – SwissCoder

+0

아니요, 그 날은 이제 막 떨어질 것입니다. – user2122092

답변

1

당신은 쉽게 다음을 수행 할 수있다. @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

이 조금 추한,하지만이 일은이다 :

  1. @firstSameDayInMonth@d 같은 요일과 달의 첫 날을 가져옵니다.
  2. 어떤 주 # @d이 해당 월에 0- 기준 정수 @weekInMonth 인지를 계산합니다. 이것은 @firstSameDayInMonth@d 사이의 주입니다.
  3. @m의 첫 번째 날을 @y과 같은 평일 인 @d@corrFirstSameDay으로 가져옵니다.
  4. 결과를 얻으려면 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))) 
+0

고맙습니다. 이것은 매우 도움이되었다! 그냥 메모, 마지막 "추한"선택 진술 첫 번째 예제에서 다른 결과를 얻을 수 있습니다. 또한 datefromparts는 2012 년 동안 만 제공됩니다.다시 한 번 감사드립니다! – user2122092

+0

@ user2122092 죄송합니다. 복사/붙여 넣기가 잘못되었습니다. 그리고 네, datefromparts는 2012 년 동안이지만 문자열 변환을 할 수 있고 피할 수 있다면 좀 더 읽기 쉽습니다. 필요한 경우 대체하십시오. –