Рекурсивный оператор SQL (PostgreSQL 9.1.4)

PostgreSQL 9.1

Деловая ситуация

Каждый месяц для определенного процесса создается новая партия учетных записей. Каждая партия может быть описана по месяцам, количеству счетов и общему балансу счетов. Целью процесса является возврат части баланса от клиентов. Каждая партия затем отслеживается отдельно на ежемесячной основе (сумма, восстановленная за каждый месяц с момента передачи партии в процесс ).

Цель

Моя цель — предсказать, какая сумма будет возмещена в будущем.

Определение данных

create table vintage_data (
    granularity date,       /* Month when account entered process*/
    distance_in_months integer, /* Distance in months from date when accounts entered process*/
    entry_accounts integer,     /* Number of accounts that entered process in a given month*/
    entry_amount numeric,       /* Total amount for account that entered process in a given month*/
    recovery_amount numeric     /* Amount recovered in Nth month on accounts that entered process in a given month */
);

Пример данных

insert into vintage_data values('2012-01-31',1,200,100000,1000);
insert into vintage_data values('2012-01-31',2,200,100000,2000);
insert into vintage_data values('2012-01-31',3,200,100000,3000);
insert into vintage_data values('2012-01-31',4,200,100000,3500);
insert into vintage_data values('2012-01-31',5,200,100000,3400);
insert into vintage_data values('2012-01-31',6,200,100000,3300);
insert into vintage_data values('2012-02-28',1,250,150000,1200);
insert into vintage_data values('2012-02-28',2,250,150000,1600);
insert into vintage_data values('2012-02-28',3,250,150000,1800);
insert into vintage_data values('2012-02-28',4,250,150000,1200);
insert into vintage_data values('2012-02-28',5,250,150000,1600);
insert into vintage_data values('2012-03-31',1,200,90000,1300);
insert into vintage_data values('2012-03-31',2,200,90000,1200);
insert into vintage_data values('2012-03-31',3,200,90000,1400);
insert into vintage_data values('2012-03-31',4,200,90000,1000);
insert into vintage_data values('2012-04-30',1,300,180000,1600);
insert into vintage_data values('2012-04-30',2,300,180000,1500);
insert into vintage_data values('2012-04-30',3,300,180000,4000);
insert into vintage_data values('2012-05-31',1,400,225000,2200);
insert into vintage_data values('2012-05-31',2,400,225000,6000);
insert into vintage_data values('2012-06-30',1,100,60000,1000);

Процесс расчета

Вы можете представить данные в виде треугольной матрицы (Значения X должны быть спрогнозированы):

distance_in_months                       1      2     3       4      5      6
granularity entry_accounts  entry_amount
2012-01-31  200             100000       1000   2000   3000   3500   3400   3300
2012-02-28  250             150000       1200   1600   1800   1200   1600   (X-1)
2012-03-31  200              90000       1300   1200   1400   1000   (X0)   (X4)
2012-04-30  300             180000       1600   1500   4000   (X1)   (X5)   (X8)
2012-05-31  400             225000       2200   6000   (X2)   (X6)   (X9)   (X11)
2012-06-30  100              60000       1000   (X3)   (X7)   (X10)  (X12   (X13)

Алгоритм

Моя цель — спрогнозировать все недостающие точки (будущего ). Чтобы проиллюстрировать процесс, это расчет для точки X1

1 )Получить итоговые данные по строкам за предыдущие три месяца, используя расстояние до 4:

2012-01-31  1000+2000+3000+3500=9500 (d4m3)
2012-02-28  1200+1600+1800+1200=5800 (d4m2)
2012-03-31  1300+1200+1400+1000=4900 (d4m1)

2 )Получить итоговые данные по строкам за предыдущие три месяца, используя расстояние до 3:

2012-01-31  1000+2000+3000=6000 (d3m3)
2012-02-28  1200+1600+1800=4600 (d3m2)
2012-03-31  1300+1200+1400=3800 (d3m1)

3 )Рассчитать средневзвешенную скорость бега для дистанции 3 и дистанции 4 (, взвешенную по вводу _количества):

(d4m3+d4m2+d4m1)/(100000+150000+90000) = (9500+5800+4900)/(100000+150000+90000) = 20200/340000 = 0.0594
(d3m3+d3m2+d3m1)/(100000+150000+90000) = (6000+4600+3800)/(100000+150000+90000) = 14400/340000 = 0.0424

4 )Вычислить разницу между расстоянием 3 и расстоянием 4

((d4m3+d4m2+d4m1)/(100000+150000+90000))/((d3m3+d3m2+d3m1)/(100000+150000+90000)) =
= (20200/340000)/(14400/340000) =
= 0.0594/0.0424 = 1.403 (PredictionRateForX1)

5 )Вычислить итоги строки для прогнозируемого месяца, используя расстояние до 3:

2012-04-30  1600+1500+4000=7100

6 )Рассчитать курс, используя ввод _суммы для прогнозируемого месяца

7100/180000 = 0.0394

7 )Расчет скорости, предсказанной для X1

0.0394 * PredictionRateForX1 = 0.05534

8 )Рассчитать сумму для X1

(0.05534-0.0394)*180000 = 2869.2

Проблема

Проблема заключается в том, как вычислить оставшуюся часть матрицы (от x -1 до x13 )с помощью оператора SQL. Очевидно, что для этого потребуется какой-то рекурсивный алгоритм.

10
задан wildplasser 20 July 2012 в 13:21
поделиться