基于SQL中先前行的总和查找总扣减额

基于SQL中先前行的总和查找总扣减额,sql,oracle,oracle10g,Sql,Oracle,Oracle10g,我有一个相当棘手的问题,这几天我一直在努力解决。我目前正在用oraclesqlmodel子句解决这个问题,可能已经编写了一个函数,但我正在寻找一个使用分析函数或其他东西的简单解决方案,但我什么都想不出来 对于给定的保单(ddpsid),我想对扣除额列(DDPC)进行汇总。[很抱歉,列名太难了,它们不是我的]。听起来很简单,但是如果ddbnep列是“Y”,那么我想总结所有之前的扣减,并将当前扣减作为已经扣减的百分比。因此,如果当前扣减额为10%,而之前的扣减额为20%(即剩余80%),那么我想扣减

我有一个相当棘手的问题,这几天我一直在努力解决。我目前正在用oraclesqlmodel子句解决这个问题,可能已经编写了一个函数,但我正在寻找一个使用分析函数或其他东西的简单解决方案,但我什么都想不出来

对于给定的保单(ddpsid),我想对扣除额列(DDPC)进行汇总。[很抱歉,列名太难了,它们不是我的]。听起来很简单,但是如果ddbnep列是“Y”,那么我想总结所有之前的扣减,并将当前扣减作为已经扣减的百分比。因此,如果当前扣减额为10%,而之前的扣减额为20%(即剩余80%),那么我想扣减8%(10%或80%),总计28%

以下代码是我当前使用的代码:

with my_sample_data as (
  select 1 as ddpsid, ddddsq, ddddpc, ddbnep, ddadep
  from (
    select 1 as ddddsq, 10 as ddddpc, 'N' as ddbnep, 'Y' as ddadep from dual union all
    select 2 as ddddsq, 10 as ddddpc, 'Y' as ddbnep, 'Y' as ddadep from dual union all
    select 3 as ddddsq, 10 as ddddpc, 'N' as ddbnep, 'Y' as ddadep from dual union all
    select 4 as ddddsq, 10 as ddddpc, 'Y' as ddbnep, 'Y' as ddadep from dual
  )
)
--        select
--            ddpsid,
--            cumul as ddddpc
--        from (
          select
            ddpsid,
            ddddsq,
            ddadep,
            ddbnep,
            ddddpc,
            rn,
            num_rows,
            100 * (1-cumul) as cumul
          from my_sample_data a
          where ddadep = 'Y'
          model
          return all rows
          partition by (ddpsid)
          dimension by (row_number() over(partition by ddpsid order by ddddsq) as rn)
          measures (ddddsq, ddadep, ddddpc, ddbnep, 0 as cumul,
                        count(*) over(partition by ddpsid) as num_rows)
          rules automatic order (
            cumul[rn] = case
                          when nvl(ddbnep[cv(rn)],'N') = 'N'
                            then nvl(cumul[cv(rn)-1],1)- ddddpc[cv(rn)] /100
                          else nvl(cumul[cv(rn)-1],1)* (1- ddddpc[cv(rn)]/100) end
          )
--        )
--        where rn = num_rows
数据将按ddpsid分组,并按DDQ的顺序进行处理。ddpsid和ddddsq的组合应该是唯一的。扣除百分比在DDPC列中。我只想处理ddadep='Y'的行。最后,如果ddbnep列='N',那么我只想将DDPC添加到运行总数中,否则如果ddbnep='Y',我想将DDPC作为百分比(100%-运行总数)添加到运行总数中

注释掉的代码是必要的,因为我实际上只需要每个ddpsid的最后一个值,但如果没有这个值,它会更好地显示工作情况

很抱歉问了这么长的问题,但这是我能提供的最简洁的描述

上面的代码显示了四项扣减,两项正常扣减和两项先前扣减的净额

  • 第一个为10%是正常的,总运行率为10%
  • 第二个为10%,是之前的净额。之前的扣除额合计为10%,因此剩余金额为90%。因此,该扣减额应为9%,即总扣减额为19%
  • 第三个为10%,为正常值,总运行率为29%
  • 10%的最终价格也扣除了之前的价格。之前的扣除额总计为29%,因此剩余金额为71%。因此,该扣减额应为7.1%,即连续总扣减额为36.1%
在花了两三天的时间试图找到解决这个问题的SQL解决方案后,我有点失望,因为我不能,我希望我没有错过任何东西

那么,有没有办法在不使用model子句和不编写函数的情况下重写它

对于查询,您需要根据以前计算的值计算值。 这是一种只能使用SQL模型子句或递归子查询分解有效完成的操作类型。后者在版本11g发行版2中引入。你可以读到关于它的信息,然后。 因为我不知道你的版本,我不知道这个建议有多有用

但是为什么不使用model子句就要重写它呢

顺便说一句,如果使用以下变量,您可以稍微简化查询:

SQL> with my_sample_data as
  2  ( select 1 as ddpsid, ddddsq, ddddpc, ddbnep, ddadep
  3      from ( select 1 as ddddsq, 10 as ddddpc, 'N' as ddbnep, 'Y' as ddadep from dual union all
  4             select 2 as ddddsq, 10 as ddddpc, 'Y' as ddbnep, 'Y' as ddadep from dual union all
  5             select 3 as ddddsq, 10 as ddddpc, 'N' as ddbnep, 'Y' as ddadep from dual union all
  6             select 4 as ddddsq, 10 as ddddpc, 'Y' as ddbnep, 'Y' as ddadep from dual
  7           )
  8  )
  9  select ddpsid
 10       , ddddsq
 11       , 'Y' as ddadep
 12       , ddbnep
 13       , ddddpc
 14       , rn
 15       , num_rows
 16       , cumul
 17    from my_sample_data a
 18   where ddadep = 'Y'
 19   model
 20         partition by (ddpsid, count(*) over (partition by ddpsid) as num_rows)
 21         dimension by (row_number() over (partition by ddpsid order by ddddsq) as rn)
 22         measures (ddddsq, ddddpc, ddbnep, 0 as cumul)
 23         ( cumul[any] order by rn
 24           = case nvl(ddbnep[cv()],'N')
 25             when 'N' then
 26               nvl(cumul[cv()-1],0) + ddddpc[cv()]
 27             when 'Y' then
 28               100 - ((100 - nvl(cumul[cv()-1],0)) * (1-ddddpc[cv()]/100))
 29             end
 30         )
 31  /

    DDPSID     DDDDSQ D D     DDDDPC         RN   NUM_ROWS      CUMUL
---------- ---------- - - ---------- ---------- ---------- ----------
         1          1 Y N         10          1          4         10
         1          2 Y Y         10          2          4         19
         1          3 Y N         10          3          4         29
         1          4 Y Y         10          4          4       36.1

4 rows selected.
希望这有帮助

问候,,
Rob。

我在10.2上,所以递归子查询分解是不可能的。我以前从未使用过示范条款,因为我从未发现有这种需要。并不是我不想使用它,我只是觉得必须有另一个解决方案,我看不到。。。。但看起来好像没有。