选择当前记录和以前记录的Oracle sql查询

选择当前记录和以前记录的Oracle sql查询,sql,oracle,merge,oracle11g,query-performance,Sql,Oracle,Merge,Oracle11g,Query Performance,我有一个表,其中包含所有带有Quantity列的事务。需要计算每个交易行中交易组和更新数量的累计总数 交易表: id(PK) group_id, txn_id, txn_date, Quantity, cumulative_qty 1 1 111 12-AUG-14 10 10 2 1 112 13-AUG-14 -5 5 3

我有一个表,其中包含所有带有Quantity列的事务。需要计算每个交易行中交易组和更新数量的累计总数

交易表:

 id(PK) group_id, txn_id, txn_date,   Quantity, cumulative_qty    
  1            1      111     12-AUG-14    10            10
  2            1      112     13-AUG-14    -5             5  
  3            1      113     14-AUG-14     2             7
  4            2      221     23-AUG-14    15            15   
  5            2      222     23-AUG-14    15            30
我写了合并到脚本,它是工作文件。但问题是它也在更新旧记录。此表有大量数据,这是性能问题

现在我需要一个合并脚本,该脚本只需要获取未处理的新记录累计数量为NULL,并使用最后一个累计数量值添加数量

假设,如果同一组有任何新事务,则选择合并应该单独拾取旧记录和新记录,并更新新记录

id(PK) group_id, txn_id, txn_date,     Quantity, cumulative_qty    
  6            1      114     25-AUG-14     5             NULL
  7            2      223     25-AUG-14    -10            NULL 
我正在使用Oracle11g。请帮助我在单个合并sql查询中编写逻辑?

关键思想是使用lag窗口函数获取以前的累积数量

使用合并:

或作为更新语句:

update
  txn t1
set
  cumulative_qty = quantity + (
    select prev_cum_qty from (
      select
        txn_id,
        lag(cumulative_qty, 1) over (
          partition by group_id 
          order by txn_id
        ) as prev_cum_qty
      from
        txn t2
      ) x
    where
        t1.txn_id = x.txn_id
  ) 
where
  cumulative_qty is null;

最后在什么上下文中?每天,每个组id?您的表必须包含txn\u id列。这是什么意思?@Mihai最新的txn。在这种情况下,ID6和ID7行是需要处理的最新记录。为此,我的SQL查询只需要考虑行3、5、6、7。任何人都可以帮助微调@劳伦斯查询,只为这个情况只得到4行吗?嗨@劳伦斯。谢谢你的合并查询。它工作得很好。从性能角度来看,select查询返回所有7行进行处理,然后合并2行。但是我希望select查询只返回4行id-3,5,6,7,即按最大日期和id的最后累计行顺序,并且只返回未处理的行。@SureshRajagopal您可以尝试将where子句放在内嵌视图中,但我认为可能存在fencepost错误。对你来说,测试是非常简单的。
update
  txn t1
set
  cumulative_qty = quantity + (
    select prev_cum_qty from (
      select
        txn_id,
        lag(cumulative_qty, 1) over (
          partition by group_id 
          order by txn_id
        ) as prev_cum_qty
      from
        txn t2
      ) x
    where
        t1.txn_id = x.txn_id
  ) 
where
  cumulative_qty is null;