2012-10-19 1 views
1

시작 값 @pStartingValuerorDateror이 포함 된 테이블을 보면 TSQL을 사용하여 각 날짜에 NAV를 얻는 가장 효율적인 방법은 무엇입니까?SQL의 순자산 가치로 수익률을 롤업하려면 어떻게해야합니까?

이 수학적으로 사소하고 간단한 코드입니다. 커서에 의존하는 순진한 SQL 구현이 현재 있습니다. 첫 데이트에

는 NAV는 이전에 계산 된 탐색 *의 ROR 또는 그것의 @pStartingValue * 모든 이전 ROR

효율적으로 할 것입니다 방법이 있어요, 이후의 모든 날짜에 @pStartingValue의 *의 ROR
입니다 MSSQL2005 +에서만 가능합니까?

DECLARE @rorDate DATE 
DECLARE @getDate CURSOR 
DECLARE @lastNAV as DECIMAL(19,7) 
DECLARE @datedRoR as float 
DECLARE @NAVTotals TABLE 
(
    NAV DECIMAL(19,7), 
    navDate DATE 
) 


SET @lastNAV = 100 

SET @getDate = CURSOR FOR 
    SELECT 
     p.[DATE] 
    FROM 
     performance p 
    ORDER BY 
     p.[DATE] 

OPEN @getDate 
FETCH NEXT 
FROM @getDate INTO @rorDate 
WHILE @@FETCH_STATUS = 0 
BEGIN 

SELECT 
    @datedRoR = b.finalNetReturn 
FROM 
    performance b 
WHERE 
    b.date = @rorDate 

INSERT INTO @NAVTotals (NAV, navDate) 
    VALUES (@lastNAV * (1 + @datedRoR), @rorDate) 

SELECT 
    @lastNAV = c.NAV 
FROM 
    @NAVTotals c 
WHERE 
    c.navDate = @rorDate 


FETCH NEXT 
FROM @getDate INTO @rorDate 
END 
CLOSE @getDate 
DEALLOCATE @getDate 

select * from @NAVTotals 
+2

커서 접근 방식을 사용하면 예상 출력과 일치하는 결과를 얻을 수 있습니다. – RThomas

+0

@RThomas 커서 구현을 추가했습니다 – Matthew

답변

1

성능이 향상되는지 테스트하려면 약간의 테스트가 필요하지만 커서를 사용하지 않고 동일한 작업을 수행하는 방법입니다. 테스트를 거치지 않으므로 테스트되지 않습니다. b.finalNetReturn을 이미 float로 캐스팅했습니다. 이미 float 인 경우 해당 부분을 제거 할 수 있습니다. 당신이 모두를 업데이트 할 수 있습니다 UPDATE 문에 lastNAV 변수를 놓아


DECLARE @lastNAV as DECIMAL(19,7) 

SET @lastNAV = 100  

DECLARE @NAVTotals TABLE 
(
    NAV DECIMAL(19,7), 
    navDate DATE 
); 

INSERT INTO @NAVTotals (navDate) 
    SELECT [DATE] 
    FROM performance 
    ORDER BY [DATE] ASC; 

UPDATE NT 
SET @lastNAV = Nav = (@lastNAV * (1.0 + 
(Cast((SELECT b.finalNetReturn 
     FROM performance b 
     WHERE b.date = NT.navDate) AS FLOAT)))) 
FROM @NAVTotals NT; 

SELECT * FROM @NAVTotals ORDER BY navDate; 

. 작동 방식 :

a = a + 1 

example of this same approach here이 있습니다. 접근법의 효율성을 커서와 같은 다른 접근법과 비교하는 좋은 숫자를 포함합니다.

+0

@lastNAV가 어떻게 설정되는지 모르십니까? 이것은 효과가있는 것처럼 보이지 않습니다. – Matthew

+0

죄송합니다. 생각보다 빨리 입력하고있었습니다. 한번보세요. 이것이 제대로 작동해야한다고 생각합니다. 과거에는 총 유형 작업을 실행하는 데 사용한 방법이었습니다. 네가하려는 일에 대해 내가 잘못 이해했다면 알려줘. – RThomas

+0

실행하지 않고 스칼라 변수 @NAVTotals를 선언해야하며 하위 참조에서 스칼라로 테이블 참조를 사용할 수 없습니다. – Matthew

0

아마 내가 제대로 이해하지 못 하겠지만 이것을 달성하기 위해 저장된 proc 파일이 필요하지 않습니다.

SELECT p.[DATE] AS navDate 
    , @pStartingValue * PRODUCT(1 + b.finalNetReturn) AS NAV 
    FROM performance p 
INNER JOIN performance b 
    ON b.[DATE] <= p.[DATE] 
GROUP BY p.[DATE] 
ORDER BY p.[DATE] 

그러나 나는 이해하지 못하는 몇 가지 "wierdness"가 있습니다.

  1. 어떻게 [날짜]에 대한 범위 제한이 있습니까?
  2. "성능"테이블에 실제로 자산이 하나만 있습니까?
+0

당신의 질의는 작동하지 않을 것입니다, 그것은 단지 각 ror에 의해 startvalue를 곱합니다, 그러나 그것들을 누적하지 않습니다. 그리고 아니, 테이블에 여러 자산이 있지만 한 번에 하나씩 액세스하므로 필요에 따라 'WHERE'절을 추가 할 수 있습니다. 방금 샘플에서 제거했습니다. – Matthew

+0

실행 했습니까? PRODUCT는 집계 함수입니다. 별칭 p 또는 b에 주목하십시오. –

+0

MSSQL에는 'PRODUCT' 집계 함수가 없습니다. – Matthew