# Oracle: Zwischensummen



## Communicate (28. Januar 2009)

Hallo und Guten Morgen, 

ich hätte da mal wieder ein Problem:

Ich habe zwei Tabellen:

Rechnung und Rechnung_historie. In der Tabelle Rechnung steht immer der 
"Ausgangswert" in der Tabelle Rechnung_historie werden sämtliche Veränderungen
dokumentiert. 

In der Tabelle Rechnung sind folgende Felder relevant:

Tabellen_Name
Rechnung_ID
Rechnung_Betrag
Rechnung_Nummer

In der Tabelle Rechnung_historie sind folgende Felder relevant:

Tabellen_Name
Rechnung_ID
Rechnung_Betrag_offen
Rechnung_Betrag_offen_Dif
Rechnung_Datum

So, was will ich eigentlich? 

Gejoint werden die beiden Tabellen über die Spalten "Tabellen_Name" und "Rechnung_ID".

Sobald mit einer Rechnungsnummer irgendwas passiert, wird die Veränderung in der Tabelle Rechnung_historie durch die Spalte Rechnung_Betrag_offen_Dif dokumentiert.

Das ganze sieht an einem Beispiel dann so aus:

1. Rechnung wird erfasst: Rechnung.Rechnung_Betrag erhält einen Wert (z.B. 5.000,00)

2. Automatisch wird in der Tabelle Rechnung_historie die Spalte Rechnung_Betrag_offen_Dif mit dem Wert 5.000,00 als Veränderung gefüllt (vorher war der Wert dann 0).

3. Kunde bezahlt seine Rechnung teilweise . Das Feld Rechnung.Rechnung_Betrag bleibt konstant beim Wert (im Beispiel 5.000,00). Das Feld Rechnung.historie.Rechnung_Betrag_offen_Dif bekommt als Veränderung den Wert -3.000,00.

Somit ist die Rechnung ersteinmal auf 2.000,00 geschrumpft  und das Endergebnis zur jeweiligen Beleg-Nr. ist 2000,00. 

Ich kann jetzt natürlich jede Rechnung einzeln auflisten und mir den Verlauf ansehen, dass ist nicht weiter schwierig:


```
SELECT rechnung.table_name,   
         rechnung_historie.rechnung_betrag_offen,   
         rechnung.beleg_nr,   
         rechnung_historie.buchungsdatum,   
         rechnung_historie.rechnung_betrag_offen_dif_hw_fir,   
         rechnung.rechnung_betrag_hw_fir  
    FROM beleg,   
         beleg_historie 
   WHERE rechnung_historie.table_name = rechnung.table_name  and  
         rechnung_historie.beleg_id = rechnung.beleg_id
```

Aber ich möchte eigentlich gleich die aggregierte Fassung.
Sprich, das Ziel soll es sein, dass mir im oben angeführten Beispiel alle Rechungs-Nummern angezeigt werden und dazu deren derzeit aktueller Stand. Rechnungen, die komplett bezahlt sind, sollen gar nicht erst ausgwiesen werden.

Ich steh wirklich auf dem Schlauch und bin für jede Hilfe dankbar!

Viele Grüße
Communicate


----------



## planb2000 (28. Januar 2009)

Hi,

ich würde mir aus der Tabelle mit den Rechnungeshistorien die summen bilden.

```
SELECT
     rechnung_id
     ,Rechnung_Betrag - sum(Rechnung_Betrag_offen)  delta
FROM
         beleg 
JOIN 
       beleg_historie  using (rechnung_id,table_name)
GROUP BY
     rechnung_id, Rechnung_Betrag
HAVING
   Rechnung_Betrag - sum(Rechnung_Betrag_offen) >0
```

Ich weis leider nicht ob das mit dem HAVING so geht, ansonsten mach noch ein SELECT außen rum und prüfe auf ">0" , also so hier:

```
SELECT *
FROM
(
SELECT
     rechnung_id
     ,Rechnung_Betrag - sum(Rechnung_Betrag_offen)  delta
FROM
         beleg 
JOIN 
       beleg_historie  using (rechnung_id,table_name)
GROUP BY
     rechnung_id, Rechnung_Betrag
)
WHERE delta > 0
```

Viele Güße


----------



## Communicate (28. Januar 2009)

Hi, erstmal danke für die schnelle Hilfe.

Ich denke, so wird es leider nicht klappen. Rechnung_Betrag_offen ist ja ein Feld aus der Tabelle Rechnung. 
Meiner Meinung nach müsste man aber die Summe aus Rechnung_historie.rechnung_betrag_offen_dif_hw_fir bilden.
Aber die Tabelle wird ja erst später eingefügt *bin verwirrt*

Ich hab das Beispiel trotzdem mal probiert. Es bricht leider immer mit dem Fehler ORA-25154: Spaltenteil von USIN-Klausel darf keinen Bezeichner haben ab... Egal ob ich die erste oder die zweite Variante teste...

Vielleicht hast Du ja noch ne Idee?

Viele Grüße
Communicate


----------



## Exceptionfault (28. Januar 2009)

Ungetestet würde ich folgenden Ansatz wählen. 


```
SELECT   Tabellen_Name,
         Rechnung_ID,
         SUM(Betrag)
FROM 
(
  SELECT   Tabellen_Name,
           Rechnung_ID,
           Rechnung_Betrag as Betrag
  FROM     Rechnung
  UNION ALL
  SELECT   Tabellen_Name,
           Rechnung_ID,
           SUM(Rechnung_Betrag_offen_Dif) as Betrag
  FROM     Rechnung_historie
  GROUP BY Tabellen_Name,
           Rechnung_ID
)
GROUP BY Tabellen_Name,
         Rechnung_ID
HAVING   SUM(Betrag) != 0;
```

Man nimmt einfach alle Sätze zusammen in eine Menge und gruppiert bzw. summiert auf, wobei die "Rechnung_Betrag_offen_Dif" Spalte natürlich negativ sein muss.


----------



## Communicate (28. Januar 2009)

Hey, vielen Dank erstmal!

Folgendes problem: Die Beleg_nr ist nicht die beleg_id.
Die beleg_id und die table_name wird nur für den Join der beiden Tabellen benötigt.
Das Merkmal, nachdem ich die Daten aber aggregieren will ist die beleg_nr aus der tabelle rechnungen. 
Um den Datumsbereich eingrenzen zu können, benötige ich auch noch die Spalte Rechnung_historie.buchungsdatum.
Ich hab also pro Tabelle jeweils eine Spalte, die nicht in der anderen Tabelle vorhanden ist. 

Wie kriege ich das denn jetzt noch hin? So ganz verstanden hab ich die Syntax leider noch nicht :-(

Liebe Grüße
Communicate


----------

