sum und join

Hallo zusammen,

ich hab das Problem das sum() bei einem join die Werte teilweise doppelt zählt. Warum das so ist ist mir auch klar, nur hab ich keine Ahnung wie ich das elegant umgehen kann.

Bsp:

postgres=# select * from kunden;
 kundennr | volumen1 | volumen2 |  name  | verkaeufer_id
----------+----------+----------+--------+---------------
        1 |      200 |      300 | Kurz   |             1
        2 |      200 |      300 | Lang   |             1
        3 |      200 |      300 | Mittel |             1
        4 |        8 |        1 | Korn   |             2
(4 Zeilen)


postgres=# select * from umsatz;
 kundennr | kundenumsatz
----------+--------------
        1 |          500
        1 |          500
        1 |          500
        1 |          300
(4 Zeilen)


postgres=# select distinct a.verkaeufer_id, sum(a.volumen1) as volumen1, sum(vol
umen2) as volumen2, sum(b.kundenumsatz) as kundenumsatz from kunden a left join
umsatz b on a.kundennr = b.kundennr group by a.verkaeufer_id order by a.verkaeuf
er_id;
 verkaeufer_id | volumen1 | volumen2 | kundenumsatz
---------------+----------+----------+--------------
             1 |     1200 |     1800 |         1800
             2 |        8 |        1 |
(2 Zeilen)


postgres=#

Das geht am einfachsten wenn Du gegen die aggregierten Werte den JOIN machst:

select a.verkaeufer_id, sum(a.volumen1) as volumen1, sum(volumen2) as volumen2, min(b.kundenumsatz) as kundenumsatz
from kunden a 
  left join (
     select kundennr, sum(kundenumsatz) as kundenumsatz
     from umsatz
     group by kundennr
  ) b on b.kundennr = a.kundennr
group by a.verkaeufer_id 
order by a.verkaeufer_id;

SQLFiddle Beispiel: http://sqlfiddle.com/#!15/36bc2/1

Das min(b.kundenumsatz) ist etwas unschön, aber notwendig wegen dem group by im äusseren select. Nachdem aber für jede kundennr genau ein umsatz geliefert wird, ändert es am Ergebnis nichts.

ich denk, so ist es schöner:

test=*# select * from kunden ;
 knr | v1  | v2  |  name  | v_id
-----+-----+-----+--------+------
   1 | 200 | 300 | kurz   |    1
   2 | 200 | 300 | lang   |    1
   3 | 200 | 300 | mittel |    1
   4 |   8 |   1 | korn   |    2
(4 rows)

Time: 0,121 ms
test=*# select * from umsatz ;
 knr | umsatz
-----+--------
   1 |    500
   1 |    500
   1 |    500
   1 |    300
(4 rows)

Time: 0,099 ms
test=*# select v_id, sum(v1) as v1, sum(v2) as v2, sum(foo.umsatz) as umsatz from kunden left join (select knr,sum(umsatz) as umsatz from umsatz group by knr) foo on foo.knr=kunden.knr group by v_id;
 v_id | v1  | v2  | umsatz
------+-----+-----+--------
    1 | 600 | 900 |   1800
    2 |   8 |   1 |
(2 rows)