Summe von Spalten (aus 2 Tabellen) berechnen oder aus einer Tabelle mit Bedingungen

Hallo,
ich habe ein kleines Problem bei der Berechnung der Summe einer Tabelle.
Tabelle1 (sorry ich weiß nicht wie man so eine Tabelle hier korrekt darstellt)
|Ware|Preis|Rabatt|Abzug|Monat|
|1’’’’’’’ |’’’’’’‘100|’’’’’’ 80|’’’’’’’ |’’’’’’’ 5|
|2’’’’’’’ |’’’’’’’’ 50|’’’’’’’-12| true|’’’’’’’ 5|
|3’’’’’’’ |’’’’’’’’ 10|’’’’’’’’ -5| true| ‘’’’’’ 6|
|4’’’’’’’ |’’’’’’’’ 40|’’’’’’’ 20| ‘’’’’’’ |’’’’’’’ 6|
|5’’’’’’’ |’’’’’’’’ 45|’’’’’’’ 10| ‘’’’’’’ |’’’’’’’ 6|
|6’’’’’’’ |’’’’’’’’-20|’’’’’’’-20| true|’’’’’’’ 6|
|7’’’’’’’ |’’’’’’’’ 90|’’’’’’’ 30| ‘’’’’’’ |’’’’’’’ 7|

Ich möchte aus dieser Tabelle die Summe aus der Spalte Preis und Rabatt berechnen und aufaddieren. Jedoch sollen in der Spalte Preis nur die Werte mit Abzug ungleich true genommen werden und in der Spalte Rabatt nur die Werte mit Abzug gleich true.
Die Werte sollen für jeden Monat aufaddiert werden, so dass folgende Ausgabe entsteht:
Nur der Endwert soll angezeigt werden.
|Monat|Summe |

| 5| 100 +(-12)= 88|
| 6| -5+40+45-20= 60|
| 7| 90= 90|

Ich weiß nicht wie ich das lösen soll, vielleicht mit 2 Select Anfragen. Und diese 2 Ergebnistabellen per Union/Join/… zusammen aufaddieren?

select Monat , sum(Preis) from Tabelle1 where Abzug is not true group by monat
Union?
select Monat , sum(Rabatt) from Tabelle1 where Abzug is true group by monat

Kann vielleicht jemand helfen oder einen anderen Weg aufzeigen?
Vielen Dank!
LG
texs89

test=*# select * from texs89 ;
 ware | preis | rabatt | abzug 
------+-------+--------+-------
    1 |   100 |     80 | f
    2 |    50 |    -12 | t
    3 |    10 |     -5 | t
    4 |    40 |     20 | f
    5 |    45 |     10 | f
    6 |   -20 |    -20 | t
    7 |    90 |     30 | f
(7 rows)

test=*# select *, case when abzug then preis - rabatt else preis end as neu_preis from texs89 ;
 ware | preis | rabatt | abzug | neu_preis 
------+-------+--------+-------+-----------
    1 |   100 |     80 | f     |       100
    2 |    50 |    -12 | t     |        62
    3 |    10 |     -5 | t     |        15
    4 |    40 |     20 | f     |        40
    5 |    45 |     10 | f     |        45
    6 |   -20 |    -20 | t     |         0
    7 |    90 |     30 | f     |        90
(7 rows)

test=*#

Dafür kann man eine gefilterte Aggregation verwenden.

select monat, 
       sum(preis) filter (where abzug is distinct from true) 
                + coalesce(sum(rabatt) filter (where abzug), 0)
from tabelle
group by monat
order by monat;

where abzug is distinct from true könnte man vereinfachen (zu where not abzug) wenn Du keine NULL Werte in der Spalte hättest, sondern dafür korrekt false verwenden würdest.

Online Beispiel

ja, castorp hat bis zu Ende gelesen :wink:

Wow perfekt, genau das habe ich gesucht, vielen vielen Dank und so schnell… :grinning:
Funktioniert wunderbar.
Eine Frage noch, es sind in der Tat null-Werte in der Tabelle.
Kann ich nicht einfach diese Bedingung nehmen -> where abzug is not true
Ist dass das gleiche wie -> where abzug is distinct from true
?
LG

Nein, weil ein Vergleich mit NULL immer “null” liefert und dass wird in diesem Zusammenhang wie “false” behandelt.

Ich würde Dir stark empfehlen, “boolean” Spalten immer mit NOT NULL zu definieren, so dass Du Dich nur mit true und false rumschlagen musst, aber nie mit NULL.

1 Like