Mittwoch, April 14, 2010

Saldo-Rechnung

Zur Beantwortung einer Frage im Tutorials-Forum habe ich heute ein kleines Beispiel zur Ermittlung von Saldo-Werten mit Hilfe der analytischen Summenfunktion gebastelt, das ich hier im Blog wahrscheinlich eher wiederfinden werde.

Gegeben sind zwei Tabellen mit asynkronen Datumsangaben, die miteinander verknüpft werden sollen, und zu deren Wert-Angaben (also Soll und Haben) ein Saldo-Wert gebildet werden soll:

-- Anlage der Testtabellen

create table test as
select to_date('01.01.2010') - 1 + (rownum * 2) datum
     , 100 wert
  from dual
connect by level < 10

DATUM            WERT
---------- ----------
02.01.2010        100
04.01.2010        100
06.01.2010        100
08.01.2010        100
10.01.2010        100
12.01.2010        100
14.01.2010        100
16.01.2010        100
18.01.2010        100

create table test2 as
select to_date('01.01.2010') + (rownum * 2) datum
     , 90 wert2
  from dual
connect by level < 10

DATUM           WERT2
---------- ----------
03.01.2010         90
05.01.2010         90
07.01.2010         90
09.01.2010         90
11.01.2010         90
13.01.2010         90
15.01.2010         90
17.01.2010         90
19.01.2010         90

Um die Tabellen zusammen zu bringen, definiere ich innerhalb der Abfrage eine Datumsreferenz, an die ich Test und Test2 dann über outer join verknüpfe und ermittle die laufenden Summen und ihre Differenz schließlich über die analytische Summenfunktion:

select t4.*
     , nvl(t4.sum_wert, 0) - nvl(t4.sum_wert2, 0) wert_diff
  from (select t3.*
             , sum(wert) over(order by datum) sum_wert
             , sum(wert2) over(order by datum) sum_wert2
          from (select ref.datum
                     , t1.wert
                     , t2.wert2
                  from (select to_date('01.01.2010') - 1 + rownum datum
                          from dual
                       connect by level < 20) ref
                  left outer join
                       test t1
                    on (ref.datum = t1.datum)
                  left outer join
                       test2 t2
                    on (ref.datum = t2.datum)
                ) t3
        ) t4;

DATUM            WERT      WERT2   SUM_WERT  SUM_WERT2  WERT_DIFF
---------- ---------- ---------- ---------- ---------- ----------
01.01.2010                                                      0
02.01.2010        100                   100                   100
03.01.2010                    90        100         90         10
04.01.2010        100                   200         90        110
05.01.2010                    90        200        180         20
06.01.2010        100                   300        180        120
07.01.2010                    90        300        270         30
08.01.2010        100                   400        270        130
09.01.2010                    90        400        360         40
10.01.2010        100                   500        360        140
11.01.2010                    90        500        450         50
12.01.2010        100                   600        450        150
13.01.2010                    90        600        540         60
14.01.2010        100                   700        540        160
15.01.2010                    90        700        630         70
16.01.2010        100                   800        630        170
17.01.2010                    90        800        720         80
18.01.2010        100                   900        720        180
19.01.2010                    90        900        810         90

Keine Kommentare:

Kommentar veröffentlichen