自我加入最大值

时间:2013-01-21 14:15:27

标签: oracle oracle10g

我有一张500k交易的表。我想获取特定日期的最后余额。所以我已经返回了如下的查询。

    SELECT curr_balance
      FROM transaction_details
     WHERE acct_num = '10'
       AND is_deleted = 'N'
       AND ( value_date, srl_num ) IN(
            SELECT MAX( value_date ), MAX( srl_num )
              FROM transaction_details
             WHERE TO_DATE( value_date, 'dd/mm/yyyy' ) 
                <= TO_DATE( ADD_MONTHS( '05-APR-2012', 1 ), 'dd/mm/yyyy' )
              AND acct_num = '10'
              AND is_deleted = 'N'
              AND ver_status = 'Y' )
       AND ver_status = 'Y'        

必须执行此操作才能增加12个月,以查找每个特定月份的最后余额。但是这个查询的cpu成本更高,是需要花费大量时间的12倍。如何重新调整上述查询以更快的方式获得结果。这是否可以在PL / SQL中分成两部分来实现性能。 ?

2 个答案:

答案 0 :(得分:0)

您不必两次查询您的表格。尝试使用analytic functions

SELECT t.curr_balance
    -- , any other column you want as long it is in the subselect.
FROM (
    SELECT
        trans.curr_balance
        , trans.value_date
        -- any other column you want
        , trans.srl_num
        , MAX(trans.srl_num) OVER(PARTITION BY trans.value_date, trans.srl_num) max_srl_num
        , MAX(trans.value_date) OVER(PARTITION BY trans.value_date, trans.srl_num) max_date
    FROM transaction_details trans
    WHERE TO_DATE( value_date, 'dd/mm/yyyy' ) <= TO_DATE( ADD_MONTHS( '01-APR-2012', 1 ), 'dd/mm/yyyy' )
        AND acct_num = '10'
        AND is_deleted = 'N'
        AND ver_status = 'Y'
) t
WHERE t.max_date = t.value_date
    AND t.max_srl_num = t.srl_num 

一些想法。

  • 为什么你有TO_DATE( value_date...?您的数据类型不是DATE吗?如果您在该列中有一个索引,则可能会破坏您的索引。
  • 请注意(这是一个疯狂的猜测),如果您的srl_num不是最新日期的最高值,则结果不正确,可能不会返回任何行。

答案 1 :(得分:0)

尝试:

select * from(
    SELECT value_date, srl_num, curr_balance
      FROM transaction_details
     WHERE acct_num = '10'
       AND is_deleted = 'N'
       AND ver_status = 'Y'  
       row_number() over (partition by trunc(value_date - interval '5' day,'MM') 
                         order by srl_num desc
                         ) as rnk
       )
where rnk = 1;

您将在表格中的每个月的最后一个srl_num上获得一份报告。

好处是您的方法会扫描表格24次,持续12个月的报告,我的方法会扫描表格一次。

分析函数获取当前月份(partition by子句)中的记录等级,对srl_num之后的月份中的行进行排序。