Eine interessante Frage an alle Experten!
Tabellen:
Kunden(kunden_nr,usw…)
Rechnungen(rech_nr,kunden_nr,betrag)
Gutschriften(gut_nr,kunden_nr,betrag)
Storno(storno_nr,kunden_nr,betrag)
Ich möchte die 4 Tabellen über Kunden_nr verknüpfen um folgende Ausgabe zu erzeugen:
Das Problem ist, daß SQL jede Rechnung mit jedem Storno verbindet
usw… und dann beim summieren die Stornos und die Gutschriften
mehrfach gezählt werden.
Ich habe das selbst nur lösen können, indem ich
mir erst von Storno und Gutschriften Sichten auf Vorrat erstellt habe, die mir jeweils die Summen liefern:
Kunden_nr,(sum(rechnungen)-storno-gutschriften)
Nun frage ich mich, ob da eine elegantere Lösung gibt.
Ich wäre für jeden Tipp dankbar.
Unter Oracle erzielst du das gewünschte Ergebinss mit einem
GROUP BY kunden_nr im SELECT Statement.
Daß ich bei kunden_nr gruppieren muß, ist mir schon klar.
Das ist ja die Voraussetzung, um die Gruppenfunktion sum()
anzuwenden.
Ein ausführliches Beispiel:
Ich habe nur einen Kunden,
2 Rechnungen zu dem Kunden von jeweils 1000,-
und 2 Stornos von jeweils 100,-
Gutschriften lassen wir mal weg.
Wenn ich jetzt die Tabellen über kunden_nr verknüpfe,
bildet SQL ein kartesisches Produkt aus diesen drei
Tabellen. D.h. es erzeugt eine 1*2*2=4 Zeilen Tabelle
und jede Rechnung und jedes Storno wird doppelt ausgegeben.
Anschließend wird gruppiert und die Summenfunktion angewandt
und ich bekomme 4000,- als Summe der Rechnungen und 400,-
als Summe der Stornos.
Ich hoffe, daß ich die Problematik jetzt verdeutlicht habe.
lustiges Problem! Mit Oracle fällt mir eine Lösung ein, ob das
auch mit MSSQL geht, weiß ich nicht, würde mich aber
interessieren, bitte Rückmeldung! Ich verwende Oracle-Spezial-
Funktionalität:
Mengenoperatoren, hier: UNION
die Möglichkeit, in der FROM-clause eine Subquery zu haben
SELECT kunden_nr, SUM (rechnungen) - SUM (storno) - SUM (gutschriften)
FROM (
SELECT kunden_nr, sum(betrag) as rechnungen, 0 as storno, 0 as gutschriften
FROM rechnungen
GROUP BY kunden_nr
UNION
SELECT kunden_nr, 0 as rechnungen, sum(betrag) as storno, 0 as gutschriften
FROM storno
GROUP BY kunden_nr
UNION
SELECT kunden_nr, 0 as rechnungen, 0 as storno, sum(betrag) as gutschriften
FROM gutschriften
GROUP BY kunden_nr)
GROUP BY kunden_nr;
Um das zu verdeutlichen: Die Subquery in der FROM-clause liefert
ein Ergebnis der Art ab:
Vielen Dank für den SuperTipp!!!
Die Möglichkeit eine Supquery in der FROM-clausel zu definieren war für mich neu und zum Glück läuft’s unter MSSQL. Ich hab’ es ausprobiert und konnte dein
Lösungsvorschlag weiter optimieren:
SELECT kunden_nr,rechnung-storno-gutschrift
FROM kunde,
(SELECT kunden_nr,sum(betrag) as rechnung from rechnung),
(SELECT kunden_nr,sum(betrag) as storno from storno),
(SELECT kunden_nr,sum(betrag) as gutschrift from gutschrift)
Anschließend verbindet man die Tabellen über kunden_nr.
Gruppierund fehlt hier weg
Die Supquery erledigt alle Zwischenrechnungen und somit
ist das Problem gelöst.