Summe nur wenn Tabelle keine null-werte enthält

Hallo,
Ich bin ganz neu hier im Forum und hab gleich mal eine Frage. Habe dazu leider in den Themen nichts gefunden.
Ich habe eine Tabelle mit mehreren Werten. Diese Datenwerte in der Tabelle (immer pro gemeinde und Jahr ein Wert) möchte ich nun mit der Summenfunktion zusammenzählen.

Gemeinde A | 2008 | 100.00
Gemeinde B | 2008 | 110.00
Gemeinde C | 2008 | 120.00
Gemeinde A | 2009 | 130.00
Gemeinde B | 2009 | null
Gemeinde C | 2009 | 140.00

Als Ergebnis möchte ich dann quasi alle Werte pro Jahr zusammenzählen. Also für 2008 gibt es dann einen Wert von 330.00. Jetzt möchte ich aber nur die Summe haben, wenn es keine Null-Werte gibt. Sobald ein Null-Wert auftritt soll die gesamte Summe auch Null sein (nicht 0).
Also anstatt 270 für das Jahr 2009 soll eben null herauskommen.

Leider habe ich jetzt keine Ahnung wie ich so etwas realsieren könnte. Kann man in PostgreSQL if bedingungen oder so etwas nutzen oder Case o-ä.? Habe da jetzt keine Idee und ich würde mich freuen, wenn mir vielleicht jemand helfen könnte.
Für Eure ferundlichen Bemühungen und eure nette Unterstützung bedanke ich mich recht herzlich im Voraus.
Hanno

Vereinfachtes Beispiel:

test=*# select * from summen ;
 a |  b
---+-----
 1 |  10
 1 |  20
 1 |  30
 2 |  10
 2 |
 3 | 100
(6 rows)

test=*# select a, sum(b) from summen where a not in (select distinct a from summen where b is null) group by 1;
 a | sum
---+-----
 3 | 100
 1 |  60
(2 rows)

Andreas

Ich bin noch ein Anfänger hier, wäre aber einen geringfügig anderen Lösungsweg als Andreas gekommen.

Der erste Teil unterscheidet sich durch das verwenden der Not Exists Klausel, wobei ich nicht weiß wie effizient Postgresql mit dieser Klausel arbeitet.

Der zweite Teil liefert den null-Werte für Jahre mit fehlenden Werten

-- Summe der vollständigen x
SELECT 
  foo.jahr
, sum(foo.x) AS sumx 
FROM foo 
WHERE 
  -- Jahre mit fehlenden x werden ausgeschlossen
  NOT EXITS (
    SELECT 1 
    FROM foo AS j 
    WHERE (j.jahr = foo.jahr a) 
      AND j.x IS NULL)
GROUP BY 1
-- Datensätze mit fehlenden x
UNION
SELECT DISTINCT
  foo.jahr
, null  AS sumx 
FROM foo
WHERE 
   -- nur Jahre mit fehlenden x werden hier angeführt
  EXITS (
    SELECT j.Jahr  
    FROM foo AS j 
    WHERE (j.Jahr = foo.jahr a) 
      AND j.x IS NULL)

Servus

Hallo,

Vielen Dank für die guten Tipps. Das hat mir schon gute Stichworte gegeben. Aber jetzt hab ich gestern die halbe Nacht versucht die Abfrage richtig hinzubekommen und scheiter leider immer wieder. Kann mir vielleicht noch einmal jemand weiterhelfen, bevor ich komplett verzweifel? ich habe jetzt einmal versucht mein Problem genauer aufzulisten. ich hoffe ihr kommt da raus und es ist nicht zu kompliziert formuliert, sodass ihr mir helfen könnt.

Als Ausgangslage habe ich zwei Tabellen (ind10019 und raumeinheiten). Diese sind über das Attribut raumeinheit verknüpft.


Tabelle ind10019

indikator | jahr | datenwert | raumeinheit

10019 | 1979 | 1 | 333
10019 | 1979 | 2 | 334
10019 | 1979 | | 335
10019 | 1979 | 3 | 339
10019 | 1979 | 4 | 344
10019 | 1979 | | 345
10019 | 1979 | | 351
10019 | 1992 | 5 | 333
10019 | 1992 | 6 | 334
10019 | 1992 | 7 | 335
10019 | 1992 | 8 | 339
10019 | 1992 | | 344
10019 | 1992 | 9 | 345
10019 | 1992 | 10 | 351
10019 | 2004 | | 333
10019 | 2004 | 11 | 334
10019 | 2004 | 12 | 335
10019 | 2004 | | 339
10019 | 2004 | 13 | 344
10019 | 2004 | 14 | 345
10019 | 2004 | 15 | 351

Tabelle raumeinheit (Verknüpfung über raumeinheit)

raumeinheit | name | pla_region

333 | “Melchnau” | 6003
334 | “Obersteckholz” | 6003
335 | “Oeschenbach” | 6003
339 | “Rohrbachgraben” | 6002
344 | “Ursenbach” | 6002
345 | “Wynau” | 6000
351 | “Bern” | 6000


SELECT jahr,indikator,pla_region,sum(datenwert) as summe
FROM ind10019,raumeinheit
where raumeinheit.raumeinheit_id=ind10019.raumeinheit
group by pla_region,jahr,indikator
order by pla_region, jahr, indikator

Ich habe es jetzt mit der Abfrage oben versucht.

Ergebnis:

jahr | indikator | raumeinheit | summe

1979 | 10019 | 6003 | 3
1979 | 10019 | 6002 | 7
1979 | 10019 | 6000 | null
1992 | 10019 | 6003 | 18
1992 | 10019 | 6002 | 8
1992 | 10019 | 6000 | 19
2004 | 10019 | 6003 | 23
2004 | 10019 | 6002 | 13
2004 | 10019 | 6000 | 29

Hierbei wird natürlich die Summe gebildet von allen Zahlen. null-Werte werden “ignoriert”. Also es werden einfach alle “echten” Werte addiert.
Ich möchte jetzt aber, dass nur die Summe gebildet wird, wenn alle Werte des entsprechenden Jahres und der entsprechenden Raumeinheit NICHT null sind.
Null gibt es bei meiner Abfrage ja nur, wenn ALLE Werte null sind für das Jahr und die Raumeinheit.

ich möchte also gern folgendes Ergebnis

jahr | indikator | raumeinheit | summe

1979 | 10019 | 6003 | null
1979 | 10019 | 6002 | 7
1979 | 10019 | 6000 | null
1992 | 10019 | 6003 | 18
1992 | 10019 | 6002 | null
1992 | 10019 | 6000 | 19
2004 | 10019 | 6003 | null
2004 | 10019 | 6002 | null
2004 | 10019 | 6000 | 29

Für Eure Versuche und eure Unterstützung gibts schonmal im Voraus ein grosses Lob und Dankeschön.
Hanno

Wohl nicht mein Tag heute, denn was besseres als dies fällt mir grad nicht ein:

-- zuerst einen VIEW zur Vereinfachung:

test=*# \d zwischenansicht ;
  View "public.zwischenansicht"
   Column   |  Type   | Modifiers
------------+---------+-----------
 jahr       | integer |
 indikator  | integer |
 pla_region | integer |
 datenwert  | integer |
View definition:
 SELECT ind10019.jahr, ind10019.indikator, raumeinheit.pla_region, ind10019.datenwert
   FROM ind10019, raumeinheit
  WHERE raumeinheit.raumeinheit = ind10019.raumeinheit
  ORDER BY raumeinheit.pla_region, ind10019.jahr, ind10019.indikator;


-- dann dies:

test=*# select jahr,indikator,pla_region, sum(datenwert) from zwischenansicht where (jahr, pla_region) not in (select distinct jahr, pla_region from zwischenansicht where datenwert is null) group by 1,2,3 union select jahr,indikator,pla_region, null from zwischenansicht where (jahr, pla_region) in (select distinct jahr, pla_region from zwischenansicht where datenwert is null) group by1,2,3;
 jahr | indikator | pla_region | sum
------+-----------+------------+-----
 1992 |     10019 |       6002 |
 1992 |     10019 |       6003 |  18
 2004 |     10019 |       6002 |
 1979 |     10019 |       6002 |   7
 1979 |     10019 |       6000 |
 2004 |     10019 |       6000 |  29
 2004 |     10019 |       6003 |
 1992 |     10019 |       6000 |  19
 1979 |     10019 |       6003 |
(9 rows)

Geht sicher noch geschickter …


Andreas