从3个表中检索值

时间:2013-04-01 10:39:12

标签: sql oracle plsql

我有三张桌子:

  1. 具有字段cons_id_no,key_id
  2. 的消费者
  3. bm_bill,其中包含字段key_id,bill_id_no,amt_payable,bill_date (它将包含所有账单金额和消费者的日期)
  4. mreceipt,其中包含字段key_id,receipt_no,amt_paid,fine, pay_date(它将包含消费者的所有付款细节)
  5. 消费者表与bm_bill和mreceipt有一对多的关系。我想根据他的cons_id_no创建消费者的分类帐信息。它应该包含他的cons_id_no,key_id,bill_id_no(最新),bill_date(最新),amt_payable(最新),receipt_no(最新),amt_paid(最新),罚款(最新),pay_date(最新)以及我创建的以下内容查询

    我已经提出了问题 here ,我找到了一个解决方案,但仍然不够,因为它是从tableS检索整个数据票据和付款。根据我从那里得到的提示,我已经达成了另一个解决方案,如下所示:

    首先我创建了一个类型:

    CREATE OR REPLACE TYPE key_id_row AS OBJECT
        (
            key_id number(10)
        );
    

    然后创建了一个表类型:

    CREATE OR REPLACE TYPE key_id_tab AS TABLE OF key_id_row;
    

    然后创建了一个函数:

    CREATE OR REPLACE FUNCTION get_key_id(cons_id VARCHAR2) RETURN key_id_tab IS
        result_tab key_id_tab;    
    BEGIN
        SELECT
            key_id_row(key_id)
        BULK COLLECT INTO 
            result_tab
        FROM
            consumer
        WHERE
            cons_id_no = cons_id;
        RETURN result_tab;    
    END get_key_id;
    

    之后我在查询中使用它如下:

    SELECT
        c.key_id,
        c.cons_id_no consumerid,
        b.bill_id_no,
        b.key_id,
        b.bill_date,
        m.key_id,
        m.receipt_no,
        m.pay_date    
    FROM
        consumer c
    LEFT OUTER JOIN
        (
            SELECT
                bb.bill_id_no,
                gk.key_id,
                bb.bill_date,
                ROW_NUMBER() OVER (PARTITION BY bb.key_id ORDER BY bb.bill_date DESC) AS rowNumber
            FROM
                bm_bill bb
            JOIN
                TABLE(get_key_id('2114109999')) gk
            ON
                (gk.key_id = bb.key_id)    
        ) b
    ON
        (b.rowNumber = 1)
    LEFT OUTER JOIN 
        (
            SELECT
                gk.key_id,
                mr.receipt_no,
                mr.pay_date,
                ROW_NUMBER() OVER (PARTITION BY mr.key_id ORDER BY mr.pay_date DESC) rowNumber
            FROM
                mreceipt mr
            JOIN
                TABLE(get_key_id('2114109999')) gk
            ON
                (gk.key_id = mr.key_id)
        ) m
    ON
        (m.rowNumber = 1)        
    WHERE
        c.cons_id_no='2114109999'; 
    

    解决方案是否足够好还是我必须通过以下方式解决问题:

    从使用者表中选择key_id作为单独的查询,如下所示:

    SELECT key_id FROM consumer WHERE cons_id_no = '2114109999';
    

    并将其存储在变量中,并在我上面提到的查询中使用该值。

1 个答案:

答案 0 :(得分:0)

您的解决方案目前正在创建与每个使用者ID相关联的key_ids表。如果您只需要最新版本,则其他thread上的答案是正确的。由于您要汇总帐单和付款表中的最新值,因此在有序表上进行子查询连接是最佳方法。

我不确定从账单和付款表中检索整个数据的含义。如果您的意思是全表扫描,那么应该通过适当的索引和/或分区来缓解这种情况。

您是否打算将您的分类帐列为消费者所有账单和付款的完整列表?您的问题给人的印象是您只关心最新的。