| 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: | Whole Thread | Raw Message | 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°
| 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 |