Re: CASE und Aggregatfunktion

From: Andreas Kretschmer <akretschmer(at)spamfence(dot)net>
To: pgsql-de-allgemein(at)postgresql(dot)org
Subject: Re: CASE und Aggregatfunktion
Date: 2009-03-26 11:52:52
Message-ID: 20090326115252.GA11603@tux
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-de-allgemein

Marc Hanisch <hanisch(at)ateam(dot)de> wrote:

> Hallo Liste,
>
> ich nutze öfter eine Query in ähnlicher Art und Weise:
>
> SELECT name,
> CASE WHEN SUM(betrag) > 0
> THEN SUM(betrag)
> ELSE 0
> END AS einnahmen,
> CASE WHEN SUM(betrag) < 0
> THEN SUM(betrag)
> ELSE 0
> END AS ausgaben
> FROM table
> GROUP BY name
>
> Erreichen will ich damit, dass ein und das selbe Feld in Abhängigkeit
> des Inhaltes also unter anderem Namen (einnahmen und ausgaben) ausgeben
> wird.
> Es erscheint mir aber umständlich, dass ich PostgreSQL für die Bedingung
> (WHEN) und für die Anweisung (THEN) um die Summierung bemühen muss, was
> ja wahrscheinlich doppelt Performance frisst... Gibt es da einen
> eleganteren Weg? Schließlich wurde die Summe des Betrages ja bei der
> ersten Bedingung bereits berechnet.

Okay, ich kann Dich beruhigen.

Ich erzeuge mir mal eine saudumme Aggregatfunktion, die eigentlich nix
weiter macht, als 1 zu liefern. Saudumm also. Nebenbei plappert sie aber
auch noch rum, immer wenn sie aufgrufen wird. Nicht so dumm für uns,
weil man dann sieht, wie oft sie aufgerufen wird:

test=# select * from summen;
i | s
---+------
1 | 10
2 | 20
3 | -5
4 | -100
(4 Zeilen)

Zeit: 0,151 ms
test=*# create or replace function agg_test(int, int) returns int as $$begin raise notice 'bin hier %',$2; return 1; end; $$language plpgsql immutable strict;
CREATE FUNCTION
Zeit: 0,695 ms
test=*# create aggregate agg_test(basetype=int, sfunc=agg_test, stype=int,initcond=1);
CREATE AGGREGATE
Zeit: 0,507 ms
test=*# select case when agg_test(s) > 0 then agg_test(s) end as einnahmen, case when agg_test(s) < 0 then agg_test(s) end as ausgaben from summen;
NOTICE: bin hier 10
NOTICE: bin hier 20
NOTICE: bin hier -5
NOTICE: bin hier -100
einnahmen | ausgaben
-----------+----------
1 |
(1 Zeile)

Wie man sieht, wird sie nur 1 mal pro Zeile aufgerufen. PG ist als
schlau genug, das zu optimieren.

Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknown)
Kaufbach, Saxony, Germany, Europe. N 51.05082°, E 13.56889°

In response to

Responses

Browse pgsql-de-allgemein by date

  From Date Subject
Next Message Marc Hanisch 2009-03-26 12:04:40 Re: CASE und Aggregatfunktion
Previous Message Marc Hanisch 2009-03-26 10:56:05 Re: CASE und Aggregatfunktion