Oracle SQL查询上一行结果

时间:2017-01-30 18:43:19

标签: sql oracle

我现在只是陷入困境,现在正在获得解决此查询的逻辑。找到下面的表格和输出。表A和表B匹配两列ID和DATE。如果Date匹配,那么它应该将qty乘以%,否则它应该选择之前的百分比。

Table A                 Table B     
ID  Date    Percent     ID  Date    Qty
A   01/01/17    0.5     A   01/01/17    10
A   04/01/17    1       A   02/01/17    20
A   06/01/17    2       A   03/01/17    30
B   02/01/17    5       A   05/01/17    40
B   05/01/17    10      A   06/01/17    50
                        A   07/01/17    60
                        A   08/01/17    40
                        B   01/01/17    10
                        B   02/01/17    50

============================================

column  column  column  comment comment comment
  ID    Date       Qty          Previous percent if row not matched 
   A    01/01/17   0.5 * 10         0.5 got new percent
   A    02/01/17   0.5 * 20         0.5 
   A    03/01/17   0.5 * 30         0.5 
   A    04/01/17   1*  0              1 got new percent but no qty found 
   A    05/01/17   1 * 40             1 
   A    06/01/17   2 * 50             2 got new percent
   B    01/01/17   10 * 0             0 no percent found
   B    02/02/17   5 * 10             5 got new percent
   B    5/1/17     10 * 0            10 got new percent

1 个答案:

答案 0 :(得分:0)

我将问题解释为"在表B"中添加更多列。 - 展示"最新的"百分比,从表A中显示其日期,以及"总数量"来自表B和"净数量"乘以适当的百分比。

如果表A中的每一行都需要一行,只需从最外层的查询中删除WHERE子句(朝向查询的底部)。

with table_a ( id, dt, pct ) as (
       select 'A', to_date('01/01/17', 'mm/dd/rr'),  0.5 from dual union all
       select 'A', to_date('04/01/17', 'mm/dd/rr'),  1   from dual union all
       select 'A', to_date('06/01/17', 'mm/dd/rr'),  2   from dual union all
       select 'B', to_date('02/01/17', 'mm/dd/rr'),  5   from dual union all
       select 'B', to_date('05/01/17', 'mm/dd/rr'), 10   from dual
  ), table_b ( id, dt, qty ) as (
       select 'A', to_date('01/01/17', 'mm/dd/rr'), 10   from dual union all
       select 'A', to_date('02/01/17', 'mm/dd/rr'), 20   from dual union all
       select 'A', to_date('03/01/17', 'mm/dd/rr'), 30   from dual union all
       select 'A', to_date('05/01/17', 'mm/dd/rr'), 40   from dual union all
       select 'A', to_date('06/01/17', 'mm/dd/rr'), 50   from dual union all
       select 'A', to_date('07/01/17', 'mm/dd/rr'), 60   from dual union all
       select 'A', to_date('08/01/17', 'mm/dd/rr'), 40   from dual union all
       select 'B', to_date('01/01/17', 'mm/dd/rr'), 10   from dual union all
       select 'B', to_date('02/01/17', 'mm/dd/rr'), 50   from dual
  )
-- end of test data (not part of the SQL query); query begins BELOW THIS LINE
select   id, qty_date, pct_date, qty as gross_qty, pct, qty * pct as net_qty
from     ( select id, dt as qty_date,
                  last_value(case flag when 0 then dt end ignore nulls)
                                    over (partition by id order by dt) as pct_date,
                  last_value(pct ignore nulls) 
                                    over (partition by id order by dt, flag) as pct,
                  qty, flag
           from   ( select    id, dt, pct, null as qty, 0 as flag
                      from    table_a
                    union all
                    select    id, dt, null as pct, qty, 1 as flag
                      from    table_b
                  )
         )
where    flag = 1       
order by id, qty_date       --  if needed
;

<强>输出

ID QTY_DATE   PCT_DATE    GROSS_QTY        PCT    NET_QTY
-- ---------- ---------- ---------- ---------- ----------
A  2017-01-01 2017-01-01         10         .5          5
A  2017-02-01 2017-01-01         20         .5         10
A  2017-03-01 2017-01-01         30         .5         15
A  2017-05-01 2017-04-01         40          1         40
A  2017-06-01 2017-06-01         50          2        100
A  2017-07-01 2017-06-01         60          2        120
A  2017-08-01 2017-06-01         40          2         80
B  2017-01-01                    10
B  2017-02-01 2017-02-01         50          5        250

9 rows selected.