2013-06-08 7 views
3

내 지급 일정에는 '유효 날짜'를 기준으로 특정 일에 지급 일정이 적용됩니다. effectivedate은 '01 잰 2013 년은 ', 그리고'EffectiveDays이 '7 인 경우테이블 기반 지급 일정

CREATE TABLE [dbo].[PaymentSchedule] (
    [PaymentScheduleId] INT IDENTITY (1, 1) NOT NULL, 
    [EffectiveDate]  DATE NOT NULL, 
    [EffectiveDays]  INT NOT NULL, 
    CONSTRAINT [pk_PaymentSchedule] PRIMARY KEY CLUSTERED ([PaymentScheduleId] ASC) 
); 

그래서, 다음, 지불은 그 이후 월 1 일, 다음 7 일마다 이루어 얻을. 따라서 1 월 8 일에 지불해야합니다. 15 일에 지불해야합니다 .. 기타 등등

effectivedate이 '01 -JAN-2013 '이고 EffectiveDays이 20 인 경우 첫 번째 지불은 1 월 1 일, 다음 지급일입니다. 1 월 21 일이고 그 다음은 2013 년 2 월 9 일이 될 것입니다 .. 등등

내가하려는 것은 위의 표를 사용하거나 그 문제에 대한 proc를 사용하는 함수를 만드는 것입니다 , '다음 지급일'을 반환하며 DATE 유형을 사용합니다. 전달 된 날짜를 기준으로 다음 지급일은 무엇입니까? 또한 '오늘은 지불 날짜입니까?'

효율적으로 수행 할 수 있습니까? 7 년 후에, 예를 들어, 날짜가 지불 일인지를 알 수 있습니까?

+0

1 월 1 일부터 7 일까지의 간격은 6 일입니다. 7 일부터 14 일까지의 간격은 7 일입니다. 당신의 예제가 정확하게 지정 되었습니까? –

+0

죄송합니다. 수정 중입니다. – Craig

답변

1

귀하의 설명은 잘못된 것입니다. 첫 번째 지불액이 1 월 1 일이면 후속 지급액이 1 월 8 일, 1 월 15 일 등이됩니다.

현재 날짜에 대한 질문에 대한 답변은 모듈러스 연산자와 함께 datediff()입니다. 오늘은 지급일 있는지, 차이를 가지고 당신이보고있는 기간의 정확한 배수 있는지 :

%
select getdate() 
from PaymentSchedule ps 
where datediff(day, ps.EffectiveDate, getdate()) % ps.EffectiveDays = 0; 

두 값 사이의 나머지를 취하는 계수 연산자가. 그래서, 3%2는 대답은 비슷 1 10%5 다음 날짜 0

입니다 : 내가 today으로 현재 날짜를 정의하는 하위 쿼리로이 구조화 한

select dateadd(day, 
       ps.EffectiveDays - datediff(day, ps.EffectiveDate, today) % ps.EffectiveDays, 
       today) as NextDate 
from PaymentSchedule ps cross join 
    (select cast(getdate() as date) as today) const 

. 이렇게하면 원하는 다른 날짜로 쉽게 대체 할 수 있습니다.

+0

이것은 유망 해 보이지만 두 번째 쿼리를 실행할 때 "피연산자 유형 충돌 : 날짜가 int와 호환되지 않습니다."오류가 발생합니다. – Craig

+0

@Craig. . . 오식. –

1

이 방법의 결과에 datepart "dayofyear"로 DATEDIFF (datepart, startdate, enddate) 설정 방법을 사용하면 두 날짜 사이의 일 수를 제공하고 모듈로 (%)로 나눕니다. EffectiveDays에 의해 그리고 결과가 0이면 지불 날이있다; 그렇지 않은 경우 마지막 지불 일로부터 일이 지났을 것입니다 (EffectivedDays에서 초록을 추출한 경우 다음 지급일까지 남은 날을 지켜야합니다). 여기

은 DATEDIFF 방법에 대한 몇 가지 문서입니다 : 문제의 http://msdn.microsoft.com/en-us/library/ms189794.aspx

0

나는 틀린 질문에 대답하고 있을지도 모르지만 나는 다음과 같은 코드가 당신이 찾고있는 것이면 선택된 지불 날짜에 도달 한 지불 일정을 반환한다고 생각한다.

IF OBJECT_ID('tempdb..#PaymentSchedules') IS NOT NULL 
    DROP TABLE #PaymentSchedules; 

CREATE TABLE #PaymentSchedules 
(PaymentScheduleID INT NOT NULL IDENTITY(1,1) 
    CONSTRAINT PK_PaymentSchedules_PaymentScheduleID PRIMARY KEY 
, EffectiveDate DATE NOT NULL 
, EffectiveDays INT NOT NULL) 
; 

INSERT #PaymentSchedules (EffectiveDate, EffectiveDays) 
VALUES 
    ('20120401', 3) 
, ('20120401', 2) 
, ('20120401', 1) 
, ('20120401', 7) 
, ('20120401', 14) 
; 

DECLARE @PaymentDate DATE = '20140310'; 

WITH myCTE AS 
(
    SELECT PaymentScheduleID, PaymentDate = EffectiveDate, EffectiveDays 
    FROM #PaymentSchedules 
    UNION ALL 
    SELECT PaymentScheduleID, PaymentDate = DATEADD(DAY, EffectiveDays, PaymentDate), EffectiveDays 
    FROM myCTE 
    WHERE DATEADD(DAY, EffectiveDays, PaymentDate) <= @PaymentDate 
) 

SELECT * FROM myCTE 
WHERE PaymentDate = @PaymentDate 
OPTION (MAXRECURSION 10000) 
;