PL SQL递归查询

时间:2011-08-01 19:37:28

标签: sql oracle plsql

请查看下表

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

TRANSACTION table
trx_id | debit | credit | type         | original_trx_id |    last_updated
1      | 0     | 0      | payment      |      null       |    25-JUL-11
2      | 0     | 2      | settlement   |        1        |    26-JUL-11
3      | 0     | 1      | settlement   |        1        |    27-JUL-11
4      | 3     | 0      | settlement   |        1        |    28-JUL-11
5      | 0     | 0      | payment      |      null       |    24-JUL-11
6      | 0     | 3      | settlement   |        5        |    25-JUL-11

RESULT EXPECTED:
trx_id | debit | credit | current_gross | current_net
2      | 0     | 2      | 10            | 12
3      | 0     | 1      | 12            | 13
4      | 3     | 0      | 12            |  9
6      | 0     | 3      | 10            | 13

说明

交易1,2,3,4属于一组,交易5,6属于另一组。可以使用上次更新的列来订购每个事务集。

对于计算,我们不采用交易类型“付款”。 “付款”交易链接到事件表。从哪里可以找到“original_gorss_amount”进行计算。

步骤

  1. 从事务表中查找事件表支付交易。 (例如:transaction_id = 1,也可以从中找到original_gross_amount = 10)
  2. 进行所有具有original_trx_id = 1
  3. 的“结算”交易
  4. 根据上次更新时间订购。
  5. 应用计算
  6. 希望你理解我的问题。我想以某种方式使用PL SQL获得“结果预期”(请不要自定义函数)

    我无法想到在这里应用CONNECT BY的方法。非常感谢您的帮助。

    请在下面找到创建表和插入语句。

    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,10,5);
    
     create table transaction
     (trx_id number(9),
      debit  number(9),
      credit number(9),
      type varchar2(50),
      original_trx_id number(9),
      last_updated DATE 
      );
    
    insert into transaction values (1,0,0,'payment',null,'2011-07-25');
    insert into transaction values (2,0,2,'settlement',1,'2011-07-26');
    insert into transaction values (3,0,1,'settlement',1,'2011-07-27');
    insert into transaction values (4,3,0,'settlement',1,'2011-07-28');
    insert into transaction values (5,0,0,'payment',null,'2011-07-24');
    insert into transaction values (6,0,3,'settlement',5,'2011-07-25');
    

1 个答案:

答案 0 :(得分:1)

如果我理解你的问题,你不需要层次结构或递归查询。只是一个带有窗口条款的分析和。

SELECT  T1.trx_id
    ,   T1.debit
    ,   T1.credit
    ,   E2.gross_amount
        + NVL( SUM( T1.credit ) OVER( PARTITION BY T1.original_trx_id
                                 ORDER BY T1.last_updated
                                 RANGE BETWEEN UNBOUNDED PRECEDING
                                            AND 1 PRECEDING ), 0 )
        - NVL( SUM( T1.debit ) OVER( PARTITION BY T1.original_trx_id
                                 ORDER BY T1.last_updated
                                 RANGE BETWEEN UNBOUNDED PRECEDING
                                            AND 1 PRECEDING ), 0 )
                                AS current_gross
    ,   E2.gross_amount
        + SUM( T1.credit ) OVER( PARTITION BY T1.original_trx_id
                                 ORDER BY T1.last_updated
                                 RANGE BETWEEN UNBOUNDED PRECEDING
                                            AND CURRENT ROW )
        - SUM( T1.debit ) OVER( PARTITION BY T1.original_trx_id
                                 ORDER BY T1.last_updated
                                 RANGE BETWEEN UNBOUNDED PRECEDING
                                            AND CURRENT ROW )
                                AS current_net
FROM    g1_transaction  T1
    ,   g1_event        E2
WHERE   T1.original_trx_id  = E2.transaction_id
ORDER BY T1.original_trx_id, T1.last_updated

注意:您的问题中的一些问题(或至少我对它的理解)。

  • 第二次插入events是否应将gross_amount设置为12
  • 结果中的trx_id 4的current_gross应该是13(而不是12),因为它包含来自trx_id 3的1个信用。因此网应该是10(而不是9)
  • trx_id 6的current_gross应该是12(而不是10),因为这是事件2的gross_amount。因此current_net将是15(而不是13)

如果这些假设是正确的,那么我提供的查询会给出这些结果。

    TRX_ID      DEBIT     CREDIT CURRENT_GROSS CURRENT_NET
---------- ---------- ---------- ------------- -----------
         2          0          2            10          12
         3          0          1            12          13
         4          3          0            13          10
         6          0          3            12          15