Хотя мне не совсем ясно, что вы хотите (пример не очень убедительный или законченный) Я могу привести вам рабочий пример, который по крайней мере (надеюсь) охватывает методологию, которую вы, кажется, хотите.
(я собираюсь составить свои собственные данные, чтобы более наглядно показать, что я имею в виду ...)
ProjectID TypeID EffectiveDate Reserve
64 4 01/01/2020 1,000
64 4 07/01/2020 5,000
64 4 11/01/2020 1,000
64 5 12/01/2020 1,000
ProjectID TypeID EffectiveDate Payment
64 4 03/01/2020 1,000
64 4 05/01/2020 1,000
64 4 09/01/2020 2,000
64 5 10/01/2020 3,000
Первым делом может показаться, что все получается в одном наборе временных рядов, а не в двух. Тогда есть текущая сумма платежей на сегодняшний день, а не отдельные суммы. Это упрощает расчет экспозиции («общее», на которое вы ссылаетесь) для каждого (ProjectId,TypeID)
.
PID,TID EffectiveDate Reserve Payment NewSpent OldSpent Exposure
64,4 01/01/2020 1,000 0 0 0 1,000 -- Reserve Added
64,4 03/01/2020 1,000 1,000 1,000 0 1,000 -- Payment Made, so newSpent increases
64,4 05/01/2020 1,000 1,000 2,000 0 2,000 -- Payment Made, so newSpent increases
64,4 07/01/2020 5,000 0 0 2,000 7,000 -- Reserve Revised, newSpent is added to OldSpent and then resets to zero
64,4 09/01/2020 5,000 2,000 2,000 2,000 7,000 -- Payment Made, so newSpent increases
64,4 11/01/2020 1,000 0 0 4,000 5,000 -- Reserve Revised, newSpent is added to OldSpent and then resets to zero
64,5 10/01/2020 0 3,000 3,000 0 3,000 -- Payment Made, so newSpent increases
64,5 12/01/2020 1,000 0 0 3,000 4,000 -- Reserve Revised, newSpent is added to OldSpent and then resets to zero
Пример SQL:
WITH
combined AS
(
SELECT
payments.ProjectID,
payments.TypeID,
links.ReserveID,
payments.DateCreated,
COALESCE(reserve.Amount, 0) AS reserve,
payments.Amount AS spent
FROM
payments
LEFT JOIN
links
ON payments.PaymentID = links.PaymentID
LEFT JOIN
reserve
ON reserve.ReserveID = links.ReserveID
WHERE
payments.status = 'Approved'
UNION ALL
SELECT
reserve.ProjectID,
reserve.TypeID,
reserve.ReserveID,
reserve.Amount,
0
FROM
reserve
)
,
runningTotal AS
(
SELECT
ProjectID,
TypeID,
DateCreated,
reserve,
SUM(spent)
OVER (PARTITION BY ProjectID, TypeID, ReserveID
ORDER BY DateCreated
)
AS spentReserve,
SUM(spent)
OVER (PARTITION BY ProjectID, TypeID
ORDER BY DateCreated
)
AS spentProjectType
FROM
combined
)
,
exposure AS
(
SELECT
ProjectID,
TypeID,
DateCreated,
reserve,
spentReserve AS spentNew,
spentProjectType - spentReserve AS spentOld,
CASE WHEN
spentReserve > reserve -- If new spending exceeds the current reserve
THEN -- The the exposure equals total spending to date
spentProjectType -- Otherwise it's the old spent value, plus the reserve
ELSE
spentProjectType - spentReserve + reserve
END
AS exposure
FROM
runningTotal
)
На этом этапе я бы свел все это к тому, насколько изменилась «Экспозиция», поскольку это упростит чередование нескольких типов.
PID,TID EffectiveDate Exposure Delta
64,4 01/01/2020 1,000 1,000 -- Reserve Added
64,4 03/01/2020 1,000 0 -- Payment Made
64,4 05/01/2020 2,000 1,000 -- Payment Made
64,4 07/01/2020 7,000 5,000 -- Reserve Revised
64,4 09/01/2020 7,000 0 -- Payment Made
64,4 11/01/2020 5,000 -2,000 -- Reserve Revised
64,5 10/01/2020 3,000 3,000 -- Payment Made
64,5 12/01/2020 4,000 1,000 -- Reserve Revised
Пример SQL :
,
deltaExposure AS
(
SELECT
exposure.*,
exposure.exposure
-
LAG(exposure.exposure, 0)
OVER (PARTITION BY exposure.ProjectID, exposure.TypeID
ORDER BY exposure.DateCreated
)
AS deltaExposure
FROM
exposure
)
Затем можно чередовать несколько типов по времени, и значения DeltaExposure суммируются по всему проекту ...
PID,TID EffectiveDate Delta ProjectExposure
64,4 01/01/2020 1,000 1,000 -- Reserve Added
64,4 03/01/2020 0 1,000 -- Payment Made
64,4 05/01/2020 1,000 2,000 -- Payment Made
64,4 07/01/2020 5,000 7,000 -- Reserve Revised
64,4 09/01/2020 0 7,000 -- Payment Made
64,5 10/01/2020 3,000 10,000 -- Payment Made
64,4 11/01/2020 -2,000 8,000 -- Reserve Revised
64,5 12/01/2020 1,000 9,000 -- Reserve Revised
Пример SQL:
,
projectExposure AS
(
SELECT
deltaExposure.*,
SUM(deltaExposure.exposure)
OVER (PARTITION BY deltaExposure.ProjectID
ORDER BY deltaExposure.DateCreated
)
AS projectExposure
FROM
deltaExposure
)
SELECT
ProjectID,
MAX(ProjectExposure) AS MaxProjectExposure
FROM
projectExposure
GROUP BY
ProjectID
Пример, показывающий, что необходим расчет изо дня в день:
Представьте проект, состоящий из двух частей Exp1 и Exp2. После расчета рисков на каждую дату события (каждый платеж или пересмотр резерва) мы получаем следующие значения «DeltaExposure».
Date 01 02 03 04 05
Exp1 +2 +2 +2 +2 -- Reserve set to 2, then payments of 4, 2 and 2
Exp2 +6 -4 +1 -- Reserve set to 6, later revised to 2, then a payment of 3
TOTAL 8 10 12 10 11
Пик воздействия приходится на дату 2-го платежа на Exp1. Средний платеж три; нет никакого способа узнать, какие Даты платежа из Exp1 являются кандидатами на пиковую подверженность без учета всех других временных рядов ...