Oracle 10g递归查询

时间:2013-03-13 10:39:00

标签: sql oracle recursion oracle10g

我有以下递归查询,它将在11g中运行但在Oracle 10g数据库中不受支持:

with st as (
    select
        rownum id,
        case  
            when rownum-1 < 1 then null
            else rownum-1
        end parent_id,
        customer, 
        tickets
    from tickets
),
st2(id, parent_id, customer, tickets, offset) as (
        select
            id, parent_id, shuffler_id, subno, contrno, tickets, 0 offset
        from st
        where id = 1
    union all
        select
            st2.id, st2.parent_id, st2.tickets, (st.tickets + st.offset) offset
        from st, st2
        where st2.parent_id = st.id
)
select * from st2

我要做的是根据以前的行列ticketsoffset(同一计算列)计算每行的偏移量,然后我开始第一行偏移量为0;事实上,我需要依赖于我在查询执行期间计算的列需要递归。

问题是Oracle 10g不支持上述查询,所以我尝试使用connect by而不是有效,但丑陋的部分是效率极低:

with st as (
    select
        rownum id,
        case  
            when rownum-1 < 1 then null
            else rownum-1
        end parent_id, 
        customer,
        tickets
    from tickets
)
select
    id, 
    parent_id,
    customer,
    tickets,
    (
        select nvl(sum(tickets), 0) from st
        where level <  x.id
        start with id = 1
        connect by prior id = parent_id
    ) offset
from st x

使用第二个查询我总结了所有以前的行,这些行完成了工作但也是多余的,我不能依赖于这个表何时增长到数百万条记录。

如何实现类似于Oracle 10g数据库中第一个查询的东西?

1 个答案:

答案 0 :(得分:3)

  select 
    id, 
    customer,
    tickets,
    nvl(
      sum(tickets) over (
        order by id rows between unbounded preceding and 1 preceding
      ), 0) as offset
  from (    
    select
        rownum id,
        customer, 
        tickets
    from tickets
  )

或更短(不引入id s)

  select 
    customer,
    tickets,
    nvl(
      sum(tickets) over (
        order by rownum rows between unbounded preceding and 1 preceding
      ), 0) as offset
  from tickets
相关问题