문제

문제가 발생합니다.

나는 매일 재무부의 가치를 보유하도록 정의 된 테이블이 있습니다. 수익률 곡선.

그것은 역사적 가치를 조회하는 데 사용되는 매우 간단한 테이블입니다.

연중 테이블에 약간의 간격이 있습니다. 4, 6, 8, 9, 11-19 그리고 21-29.

공식은 연도를 계산하는 것이 매우 간단합니다. 4 이것의 0.5*Year3Value + 0.5*Year5Value.

문제는 어떻게 a를 쓸 수 있다는 것입니다 VIEW 실종 된 해를 돌려 줄 수 있습니까?

저장된 절차에서 할 수는 있지만 최종 결과는보기가 필요합니다.

도움이 되었습니까?

해결책

가정을 취합니다 톰 H. 당신이 정말로 원하는 것은 선형 보간이며 몇 년뿐만 아니라 몇 달이 빠졌다는 사실은 해가 아닌 한 달에 모든 계산을 기반으로해야합니다.

아래 코드의 경우 2 개의 테이블이 있다고 가정합니다 (그 중 하나는보기의 일부로 계산할 수 있음).

  • 수율 : 실제 데이터를 포함하고 저장합니다 기간 이름보다는 이름이 있습니다. 당신이 저장한다면 기간 이름 거기에서, 당신은 단지 테이블에 가입하기 만하면됩니다.
  • 기간 (표시와 같이보기에서 계산할 수 있습니다): 기간 이름과 그것이 나타내는 달 수를 저장합니다.

다음 코드는 작동해야합니다.

WITH "Period" (PeriodM, PeriodName) AS (
    -- // I would store it as another table basically, but having it as part of the view would do
                SELECT  01, '1 mo'
    UNION ALL   SELECT  02, '2 mo' -- // data not stored
    UNION ALL   SELECT  03, '3 mo'
    UNION ALL   SELECT  06, '6 mo'
    UNION ALL   SELECT  12, '1 yr'
    UNION ALL   SELECT  24, '2 yr'
    UNION ALL   SELECT  36, '3 yr'
    UNION ALL   SELECT  48, '4 yr' -- // data not stored
    UNION ALL   SELECT  60, '5 yr'
    UNION ALL   SELECT  72, '6 yr' -- // data not stored
    UNION ALL   SELECT  84, '7 yr'
    UNION ALL   SELECT  96, '8 yr' -- // data not stored
    UNION ALL   SELECT 108, '9 yr' -- // data not stored
    UNION ALL   SELECT 120, '10 yr'
    -- ... // add more
    UNION ALL   SELECT 240, '20 yr'
    -- ... // add more
    UNION ALL   SELECT 360, '30 yr'
)
, "Yield" (ID, PeriodM, Date, Value) AS (
    -- // ** This is the TABLE your data is stored in **
    -- // 
    -- // value of ID column is not important, but it must be unique (you may have your PK)
    -- // ... it is used for a Tie-Breaker type of JOIN in the view
    -- //
    -- // This is just a test data:
                SELECT 101, 01 /* '1 mo'*/, '2009-05-01', 0.06
    UNION ALL   SELECT 102, 03 /* '3 mo'*/, '2009-05-01', 0.16
    UNION ALL   SELECT 103, 06 /* '6 mo'*/, '2009-05-01', 0.31
    UNION ALL   SELECT 104, 12 /* '1 yr'*/, '2009-05-01', 0.49
    UNION ALL   SELECT 105, 24 /* '2 yr'*/, '2009-05-01', 0.92
    UNION ALL   SELECT 346, 36 /* '3 yr'*/, '2009-05-01', 1.39
    UNION ALL   SELECT 237, 60 /* '5 yr'*/, '2009-05-01', 2.03
    UNION ALL   SELECT 238, 84 /* '7 yr'*/, '2009-05-01', 2.72
    UNION ALL   SELECT 239,120 /*'10 yr'*/, '2009-05-01', 3.21
    UNION ALL   SELECT 240,240 /*'20 yr'*/, '2009-05-01', 4.14
    UNION ALL   SELECT 250,360 /*'30 yr'*/, '2009-05-01', 4.09
)
, "ReportingDate" ("Date") AS (
    -- // this should be a part of the view (or a separate table)
    SELECT DISTINCT Date FROM "Yield"
)

-- // This is the Final VIEW that you want given the data structure as above
SELECT      d.Date, p.PeriodName, --//p.PeriodM,
            CAST(
                COALESCE(y_curr.Value,
                    (   (p.PeriodM - y_prev.PeriodM) * y_prev.Value
                    +   (y_next.PeriodM - p.PeriodM) * y_next.Value
                    ) / (y_next.PeriodM - y_prev.PeriodM)
                ) AS DECIMAL(9,4) -- // TODO: cast to your type if not FLOAT
            )  AS Value
FROM        "Period" p
CROSS JOIN  "ReportingDate" d
LEFT JOIN   "Yield" y_curr
        ON  y_curr.Date = d.Date
        AND y_curr.PeriodM = p.PeriodM
LEFT JOIN   "Yield" y_prev
        ON  y_prev.ID = (SELECT TOP 1 y.ID FROM Yield y WHERE y.Date = d.Date AND y.PeriodM <= p.PeriodM ORDER BY y.PeriodM DESC)
LEFT JOIN   "Yield" y_next
        ON  y_next.ID = (SELECT TOP 1 y.ID FROM Yield y WHERE y.Date = d.Date AND y.PeriodM >= p.PeriodM ORDER BY y.PeriodM ASC)

--//WHERE       d.Date = '2009-05-01'

다른 팁

목록에 연도와 가치를 얻기 위해 비트를 시도 할 수 있습니다.

그런 다음 누락 된 년까지 Universe Select Ongno (fealno = forgno-1) * 0.5 + (fealno = faverno + 1) * 0.5의 연말 값을 선택하십시오.

그런 다음 다시 회전하여 필요한 형식을 가져 와서보기로 팝업 하시겠습니까?

격차가있는 경우 곡선이 2 년 사이에 부드럽게 이동하기를 원한다고 추측 할 것입니다. 따라서 1 년 이상이 없으면 가장 가까운 2 년의 평균을 원하지 않습니다. 아마 내가 사용할 내용은 다음과 같습니다.

SELECT
     NUM.number AS year,
     COALESCE(YC.val, YC_BOT.val + ((NUM.number - YC_BOT.yr) * ((YC_TOP.val - YC_BOT.val)/(YC_TOP.yr - YC_BOT.yr))))
FROM
     dbo.Numbers NUM
LEFT OUTER JOIN dbo.Yield_Curve YC ON
     YC.yr = NUM.number
LEFT OUTER JOIN dbo.Yield_Curve YC_TOP ON
     YC.yr IS NULL AND       -- Only join if we couldn't find a current year value
     YC_TOP.yr > NUM.number
LEFT OUTER JOIN dbo.Yield_Curve YC_TOP2 ON
     YC_TOP2.yr > NUM.number AND
     YC_TOP2.yr < YC_TOP.yr
LEFT OUTER JOIN dbo.Yield_Curve YC_BOT ON
     YC.yr IS NULL AND       -- Only join if we couldn't find a current year value
     YC_BOT.yr < NUM.number
LEFT OUTER JOIN dbo.Yield_Curve YC_BOT2 ON
     YC_BOT2.yr < NUM.number AND
     YC_BOT2.yr > YC_BOT.yr
WHERE
     YC_TOP2.yr IS NULL AND
     YC_BOT2.yr IS NULL AND
     NUM.number BETWEEN @low_yr AND @high_yr

숫자 테이블 대신 CTE를 사용 하여이 글을 다시 작성할 수 있습니다 (연속 숫자 표). 또한 YC_BOT2 및 YC_TOP2에서 왼쪽 외부 조인 대신 Min 및 Max와 함께 존재하지 않거나 하위 쿼리를 사용할 수도 있습니다. 어떤 사람들은이 방법이 혼란 스럽습니다.

WITh cal(year) AS
        (
        SELECT  1 AS current_year
        UNION ALL
        SELECT  year + 1
        FROM    cal
        WHERE   year < 100
        )
SELECT  CASE WHEN yield_year IS NULL THEN
             0.5 *
             (
             SELECT  TOP 1 yield_value
             FROM    yield
             WHERE   yield_year < year
             ORDER BY
                     yield_year DESC
             ) +
             0.5 *
             (
             SELECT  TOP 1 yield_value
             FROM    yield
             WHERE   yield_year > year
             ORDER BY
                     yield_year ASC
             )
         ELSE
             yield_value
         END
FROM     cal
LEFT JOIN
         yield
ON       yield_year = year

누락 된 년 동안이 쿼리는 가장 가까운 해의 평균이 걸립니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top