Entwickler-Ecke

Datenbanken - Aggregatfunktion SUM mit Null-Werten


motion - So 22.07.07 00:32
Titel: Aggregatfunktion SUM mit Null-Werten
Ich einer Query, muss ich über die SUM-Aggregatfunktion ein Feld einer Gruppe aufsummieren. Funktioniert gut, nur wenn ein Feld dieser Gruppe NULL ist, wird die Gesamt-Summe ebenfalls NULL. ich möchte NULL Felder in diesem Falle mit 0 substituieren.
Ich habe schon im "Firebird Null Guide" geblättert und dort wird die Funktion
"Coalesce(Feld||0)" empfohlen, aber leider akzeptiert der Server die SQL-Syntax in diesem Zusammenhang nicht.
Diese Syntax ist leider illegal:

SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
select -sum(
coalesce(artikelhistorie.mengenaenderung||'0')
as verkauftezahl from artikelhistorie
where ref0=37720
and artikelhistorie.buchungstyp in (4,5,7,8,9,12,14,16)
and artikelhistorie.zeitstempel>='1.1.2006'
group by ref0


Kennt jemand noch einen anderen Weg das Problem zu lösen?


motion - So 22.07.07 01:26

Ich denke das Problem habe ich auch geknackt:

Einfach ein weitere Test, ob der zu summierende Wert is not NULL ist:


SQL-Anweisung
1:
2:
3:
4:
5:
(select -sum(artikelhistorie.mengenaenderung) from artikelhistorie
where ref0=12345
and artikelhistorie.buchungstyp in (4,5,7,8,9,12,14,16and (artikelhistorie.mengenaenderung is not Null)
and (artikelhistorie.zeitstempel between current_date-1*365 and current_date)
group by ref0) as verkaeufe_aktuell


alex517 - So 22.07.07 11:34
Titel: Re: Aggregatfunktion SUM mit Null-Werten
Hi

user profile iconmotion hat folgendes geschrieben:

"Coalesce(Feld||0)"


statt || mußt du ein , verwenden.


SQL-Anweisung
1:
Coalesce(Feld ,  0)                    


Coalesce gibt den ersten Ausdruck der Aufzählung zurück der NOT NULL ist.


alex


motion - So 22.07.07 11:50

Alex517,
stimmt! Da habe ich doch eine Weile im Firebird Null Guide rumgeglotzt und mir deren Beispiele angeschaut und dabei diese Feinheit tatsächlich übersehen.
Alles klar, danke.


mkinzler - So 22.07.07 12:02

Man könnte es auch mit CASE WHEN oder IIF versuchen


motion - So 22.07.07 15:15

Ich glaube das geht NICHT!
Denn Vergleiche IF (A = NULL) sind laut SQL Standard (steht auch so im FB Null Guide) NICHT erlaubt bzw. können zu fehlerhaften Ergebnissen führen. Einige SQL Server erlauben diese Operation zwar, aber FB lehnt das als syntaktisch falsch ab.
Test mit CASE oder IIF bei Nullwerten sind ebenso nicht erlaubt.
Tests auf NULL sollen immer mit "A is NULL" bzw. "A is not null" erfolgen!

Durch die Funktion coelesce wird Null auf Wunsch mit einem Leerstring oder 0 substituiert. Also z.B.
coalesce(A,'') -> ergibt das Feld A oder '', falls es NULL ist
coalesce(A,0) -> ergibt das Feld A oder 0, falls es NULL ist


mkinzler - So 22.07.07 15:45

Also IIf und Case when geht genauso


SQL-Anweisung
1:
SUM(IIF( <feld> is not Null, Feld, 0))                    


motion - So 22.07.07 16:51

Markus,
ah, so ist das gemeint.
Ja korrekt, wenn gegen die IS NULL bzw. IS NOT NULL Funktion getestet/verglichen wird, dann paßt es. Nur Tests auf "=NULL" bzw. "<>NULL" sind inkorrekt.