Справка по рекурсивному PL SQL-запросу - PullRequest
0 голосов
/ 28 июля 2011

У меня есть два стола.Я хочу получить приведенный ниже результат из этих двух таблиц.Любую помощь оценят.


Таблица событий

event_id | gross_amount | transaction_id
1        | 10           | 1
2        | 12           | 5

Таблица транзакций

trx_id | debit | credit | link_trx_id
1      | 4     | 0      | null
2      | 0     | 2      | 1
3      | 0     | 1      | 2
4      | 3     | 0      | 3
5      | 0     | 5      | null
6      | 0     | 3      | 5

Ожидаемый результат:

trx_id | debit | credit | current_gross | current_net
1      | 4     | 0      | 10            | 6
2      | 0     | 2      | 6             | 8
3      | 0     | 1      | 8             | 9
4      | 3     | 0      | 9             | 6
5      | 0     | 5      | 10            | 15
6      | 0     | 3      | 15            | 18

Пояснение

Как вы можете видеть транзакции 1,2,3,4 попадают в один набор, а 4,6 попадают в другой набор.Для каждой необходимой транзакции это связанное значение current_net предыдущих транзакций как его current_gross.

По сути, получение current_gross является рекурсивным вызовом.Здесь я не могу использовать функцию PL SQL, где я могу написать быструю рекурсивную функцию для вычисления current_gross.Мне нужен чистый PL / SQL-запрос для этой задачи.(Можно использовать встроенные функции PL SQL)

Ответы [ 2 ]

2 голосов
/ 29 июля 2011

Это приблизительный, непроверенный ответ (если бы вы предоставили операторы create table и insert для ваших данных / структуры, я бы проверил их).Предполагается, что в вашей таблице транзакций нет разветвлений (то есть, что link_trx_id уникально).По сути, мы используем рекурсивное объединение для получения группировки, родительской информации и порядка, а затем используем аналитические функции для получения промежуточного итога (current_net).Вместо того, чтобы пытаться получить предыдущую сумму (что мы могли бы сделать), представляется более целесообразным просто удалить текущие строки credit и debit из current_net.

SELECT trx_id,
       debit,
       credit,
       root_amt - cum_debit + cum_credit + debit - credit AS current_gross,
       root_amt - cum_debit + cum_credit AS current_net
FROM   (SELECT trx_id,
               debit,
               credit,
               SUM(credit) OVER (PARTITION BY event_id ORDER BY lvl) AS cum_credit,
               SUM(debit) OVER (PARTITION BY event_id ORDER BY lvl) AS cum_debit,
               root_amt
        FROM   (SELECT     trx_id,
                           debit,
                           credit,
                           LEVEL AS lvl,
                           CONNECT_BY_ROOT (gross_amount) AS root_amt,
                           CONNECT_BY_ROOT (event_id) AS event_id
                FROM       transaction t LEFT OUTER JOIN event e ON t.trx_id = e.transaction_id
                CONNECT BY link_trx_id = PRIOR trx_id
                START WITH link_trx_id IS NULL))
.
1 голос
/ 29 июля 2011

Используя запрос Аллана, я добавил таблицу создания и вставки.В запросе не совпадали переменные, поэтому я также исправляю их (debit_cum / credit_cum не соответствует переменным cum-credit / cum_debit в подзапросе).

create table event
(event_id   number(9),
 gross_amount number(9),
 transaction_id number(9));

 insert into event values (1,10,1);
 insert into event values (2,12,5);

 create table transaction
 (trx_id number(9),
  debit  number(9),
  credit number(9),
  link_trx_id number(9)
  );

  insert into transaction values (1,4,0,null);
  insert into transaction values (2,0,2,1);
  insert into transaction values (3,0,1,2);
  insert into transaction values (4,3,0,3);
  insert into transaction values (5,0,5,null);
  insert into transaction values (6,0,3,5);



SELECT trx_id,
       debit,
       credit,
       root_amt - debit_cum + credit_cum + debit - credit AS current_gross,
       root_amt - debit_cum + credit_cum AS current_net
FROM   (SELECT trx_id,
               debit,
               credit,
               SUM(credit) OVER (PARTITION BY event_id ORDER BY lvl) AS credit_cum,
               SUM(debit) OVER (PARTITION BY event_id ORDER BY lvl) AS debit_cum,
               root_amt,
               event_id
        FROM   (SELECT     trx_id,
                           debit,
                           credit,
                           LEVEL AS lvl,
                           CONNECT_BY_ROOT (gross_amount) AS root_amt,
                           CONNECT_BY_ROOT (event_id) AS event_id
                FROM       transaction t LEFT OUTER JOIN event e ON t.trx_id = e.transaction_id
                CONNECT BY link_trx_id = PRIOR trx_id
                START WITH link_trx_id IS NULL));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...