У меня есть премиум для политики с TransactionEffectiveDate
и TransactionExpirationDate
.
Любой способ написать запрос в DAX, который бы брал каждую премиальную сумму и делил ее на месяц между этими двумя датами.
Параметр @AsOfDate будет датой, когда политика прекращает зарабатывать.
Например:
PolicyNumber WIC1000158-00
имеет премию в размере 82 913 долларов
и TransactionEffectiveDate 1/5/2018
и TransactionExpirationDate 1/5/2019.
, что дает нам 365 дней политики.
Посмотрим, сколько мы заработали до '06 / 29/2018 '
Таким образом, премия в 82 913 должна быть разбита на 12 месяцев:
Таким образом, на первый месяц политики у нас есть только 27 дней
То есть 82 913/365 * 27 = 6 139,29 - вот сколько было заработано за первый месяц.
И так до @AsOfDate
.
Результат должен быть таким с @AsOfDate = '6/29/2018'
:
Хотя мне нужны только столбцы
YearNum
,
MonthNum
,
Qtr
EarnedPremium
Я смог написать это на SQL, но
Есть ли способ добиться этого в DAX?
.pbix файл доступен здесь:
https://www.dropbox.com/s/pbj61vsb20qbhzm/LossTriangleTest.pbix?dl=0
UPDATE !
Алексис, большое спасибо. Удивительно, что DAX может делать с числами.
По какой-то причине он всегда дает мне сумму заработанной премии чуть больше, чем первоначальная.
Например, у PolicyNumber 'PACA1000101-00' общая премия составляет 10 568 долл. США, но рассчитывается как заработанная сумма в размере 10 596 долл. США. апрель 2013 дает немного больше.
Я думаю, что некоторая дополнительная логика должна быть реализована в отношении последней разбивки (EndRiskMonth).
(Результат из Power BI. Извините, он еще не отсортирован)
Результат из SQL:
Как видите, в апреле 2013 года 26 дней.
Вот как я делаю это в SQL, если это поможет. (можно запустить в SSMS)
DECLARE @PlazaInsuranceWPDataSet TABLE (
PolicyNumber varchar(50),
TransactionEffectiveDate datetime,
TransactionExpirationDate datetime,
WrittenPremium money
)
INSERT INTO @PlazaInsuranceWPDataSet values ('PACA1000101-00', '2012-04-27','2013-04-27',6630.00 ),
('PACA1000101-00', '2012-04-27','2013-04-27',1600.00 ),
('PACA1000101-00', '2012-04-27','2013-04-27',490.00 ),
('PACA1000101-00', '2012-04-27','2013-04-27',-77.00 ),
('PACA1000101-00', '2012-04-27','2013-04-27',1925.00 )
; WITH Earned_to_date AS (
SELECT Cast('2019-06-30' AS DATE) AS Earned_to_date
), policy_data AS (
SELECT
PolicyNumber
, Cast(TransactionEffectiveDate AS DATE) AS TransactionEffectiveDate
, Cast(TransactionExpirationDate AS DATE) AS TransactionExpirationDate
, WrittenPremium
FROM @PlazaInsuranceWPDataSet
)
, digits AS (
SELECT digit
FROM (VALUES (0), (1), (2), (3), (4)
, (5), (6), (7), (8), (9)) AS z2 (digit)
), numbers AS (
SELECT 1000 * d4.digit + 100 * d3.digit + 10 * d2.digit + d1.digit AS number
FROM digits AS d1
CROSS JOIN digits AS d2
CROSS JOIN digits AS d3
CROSS JOIN digits AS d4
), calendar AS (
SELECT
DateAdd(month, number, '1753-01-01') AS month_of
, DateAdd(month, number, '1753-02-01') AS month_after
FROM numbers
), policy_dates AS (
SELECT
PolicyNumber
, CASE
WHEN month_of < TransactionEffectiveDate THEN TransactionEffectiveDate
ELSE month_of
END AS StartRiskMonth
, CASE
WHEN TransactionExpirationDate < month_after THEN TransactionExpirationDate
WHEN Earned_to_date.Earned_to_date < month_after THEN Earned_to_date
ELSE month_after
END AS EndRiskMonth
, DateDiff(day, TransactionEffectiveDate, TransactionExpirationDate) AS policy_days
, WrittenPremium
FROM policy_data
JOIN calendar
ON (policy_data.TransactionEffectiveDate < calendar.month_after
AND calendar.month_of < policy_data.TransactionExpirationDate)
CROSS JOIN Earned_to_date
WHERE month_of < Earned_to_date
)
SELECT PolicyNumber,
StartRiskMonth,
EndRiskMonth,
YEAR(StartRiskMonth) as YearNum,
MONTH(StartRiskMonth) as MonthNum,
DATEPART(qq, StartRiskMonth) AS Qtr,
policy_days,
sum(WrittenPremium) as WrittenPremium,
DateDiff(day, StartRiskMonth, EndRiskMonth) AS DaysInMonth,
sum(WrittenPremium * DateDiff(day, StartRiskMonth, EndRiskMonth) / NULLIF(policy_days,0)) as EarnedPremium
FROM policy_dates
GROUP BY PolicyNumber, StartRiskMonth, EndRiskMonth
, DateDiff(day, StartRiskMonth, EndRiskMonth),policy_days
ORDER BY PolicyNumber, StartRiskMonth
UPDATE!
Alexis
Я изменил "EoMonth" в таблице календаря EOMONTH([Month], 0)+1
--добавлено + 1
В CrossTabel "DaysInMonth", [EndRiskMonth] - [StartRiskMonth],
- снял 1
и за заработанную премию
"EarnedPremium", [Premium] *
DIVIDE([EndRiskMonth] - [StartRiskMonth] , [End] - [Start])) --took off 1.
Результат теперь выглядит так: