[NEWSboard IBMi Forum]
Seite 2 von 2 Erste 1 2
  1. #13
    Registriert seit
    Jun 2005
    Beiträge
    98
    Zitat Zitat von Andreas_Prouza Beitrag anzeigen
    Dann versuche mal mit dem Ergebnis durch 0 weiter zu arbeiten.
    Das kann ich genauso gut oder schlecht wie mit jedem anderen NULLwert. Ob ich nun eine Division durch 0 mache oder ein Feld anspreche bei dem er den zugehörigen Satz in einem Join nicht gefunden hat ist nur sekundär von Interesse.

  2. #14
    Registriert seit
    Nov 2020
    Beiträge
    315
    Das macht sehr wohl einen großen Unterschied
    Ein COALESCE(dein-Null-Value, 0) + 1 geht.
    Ein 100/0 + 1 geht eben nicht.

  3. #15
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Beachte die oben bereits mehrfach erwähnte Bedingung:

    Ist bei einem Ausdruck ein Teilergebnis NULL dann ist der gesamte Ausdruck immer NULL!

    D.h., mit NULL kann ich eben nicht weiterrechnen und genau dafür ist der Coalesce eben da.
    Da er mehrere Ausdrücke erlaubt ist es in SQL eben sehr einfach einen möglichen Wert aus mehreren Joins zu ziehen:

    select coalesce(a.value, b.value, c.value)
    from mytable m
    left join table1 a on a.key = m.key
    left join table2 b on b.key = m.key
    left join table3 a on c.key = m.key

    Desweiteren:
    STRSQL zeigt fehlerhafte Ausdrücke mit "+++++" an.
    Im embedded SQL hört der SQL i.d.R. beim ersten Fehler auf.

    Wenn ich per ODBC Daten abhole kann es sogar passieren, dass der SQL durch den Fehler vorzeitig aufhört, allerdings auch keine Fehlermeldung abgibt und ich somit gar nciht weiß, ob der SQL alles geliefert hat.
    Alles schon erlebt.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  4. #16
    Registriert seit
    Jun 2005
    Beiträge
    98
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Beachte die oben bereits mehrfach erwähnte Bedingung:

    Ist bei einem Ausdruck ein Teilergebnis NULL dann ist der gesamte Ausdruck immer NULL!

    D.h., mit NULL kann ich eben nicht weiterrechnen und genau dafür ist der Coalesce eben da.
    Da er mehrere Ausdrücke erlaubt ist es in SQL eben sehr einfach einen möglichen Wert aus mehreren Joins zu ziehen:

    select coalesce(a.value, b.value, c.value)
    from mytable m
    left join table1 a on a.key = m.key
    left join table2 b on b.key = m.key
    left join table3 a on c.key = m.key

    Desweiteren:
    STRSQL zeigt fehlerhafte Ausdrücke mit "+++++" an.
    Im embedded SQL hört der SQL i.d.R. beim ersten Fehler auf.

    Wenn ich per ODBC Daten abhole kann es sogar passieren, dass der SQL durch den Fehler vorzeitig aufhört, allerdings auch keine Fehlermeldung abgibt und ich somit gar nciht weiß, ob der SQL alles geliefert hat.
    Alles schon erlebt.
    Was ich meine ist das dies auf ALLE NULLwerte zu trifft, nicht nur auf eine Division durch 0.
    Und ja, in bestimmten PHP Versionen mit ODBC macht er dann (in dem Fall keine Div sondern eben den erwähnten Join) einen Segfault.

    Daher bin es ja gewohnt mit coalesce zu arbeiten ... intensiv. Aber das er eben bei einem coalesce(wert, 0) trotzdem ein NULL zurück gibt hatte ich noch nicht.

  5. #17
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Division durch 0 egibt erst mal kein NULL sondern immer einen Fehler.

    Den Coalesce würde ich auch gezielter analysieren und bei Wiederholbarkeit einen Fehler an IBM melden.
    Denn das darf einfach nicht passieren.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  6. #18
    Registriert seit
    Aug 2001
    Beiträge
    2.869
    Mit Common Table Expressions hättest Du Dir eine ganze Menge COALESCES und Konvertierungen sparen können, ... und da nicht immer wieder alles mögliche wiederholt werden muss, wäre das Ganze auch weniger fehleranfällig.
    Was die Casterei angeht. Wenn der Nenner eines Bruchs eine Dezimal-Zahl ist, wird intern automatisch in Float umgewandelt. Die übrigen Casts kannst Du Dir sparen. Was Du wissen musst, ist wenn du 2 Integer-Werte durcheinander dividierst wird das Ergebnis wieder ein Integer-Wert sein, d.h. Nachkommastellen werden abgeschnitten.
    Spalten-Namen, die in der SELECT-Zeile definiert wurden, können im Order By angegeben werden, d.h. es ist nicht notwendig den ganzen Ausdruck nochmals zu kopieren.

    Ich hab's mal versucht ein bisschen umzuschreiben. Da ich nicht weiß wie Deine Felder definiert sind, habe ich ausum2 explizit gecastet. (Ich kann's leider nicht testen, d.h. es könnte noch der eine oder andere Fehler drin sein.
    Code:
    With ulj as (select s3idn, sum(s3tlmg) as stlj
                    from stdprod.afs3sp
                    where     substr(s3afa, 1, 1) not in ('M', 'Y', 'Z') 
                          and s3rgd <= '20201031'
                    group by s3idn), 
         uvj as (select s3idn, sum(s3tlmg) as stvj
                    from wwdta.afs3spvj
                    where    substr(s3afa, 1, 1) not in ('M', 'Y', 'Z')
                    group by s3idn),  
         uvvj as (select s3idn, sum(s3tlmg) as stvvj
                    from wwdta.afs3spvvj
                    where    substr(s3afa, 1, 1) not in ('M', 'Y', 'Z')
                    group by s3idn),     
         bst as (select abidn, sum(abbst) as frei
                   from stdprod.afabsp
                   where substr(ablag, 3, 2) < '50'
                   group by abidn),
         xJoin as (select asidn, asbz1, asbz2,
                          coalesce(stlj,  0.00)  as stlj,
                          coalesce(stvj,  0.00)  as stvj,
                          coalesce(stvvj, 0.00)  as stvvj,
                          coalesce(frei,  0.00)  as stfrei,
                          asabc, asme2,
                          Substr(asidn, 11, 1)   as asidn111,
                          Substr(asidn, 13, 2)   as asidn132,
                          Cast(asumf2 as Dec(31, 15) as asumf2, 
                          Coalesce(".$totmon.", 00) as "$.totmon." 
                          Coalesce(Stlj, 0) + Coalesce(Stvj, 0) + coalesce(Stvvj, 0) as St3J
                      from stdprod.afassp left join ulj  on ulj.s3idn  = asidn
                                          left join uvj  on uvj.s3idn  = asidn            
                                          left join uvvj on uvvj.s3idn = asidn
                                          left join bst  on abidn = asidn)        
     
    select asidn, asbz1, asbz2,stlj, stvj, stvvj, stfrei,
           Case When asumf2 <> 0 Then Stlj   / asumf2 Else 0 End   as qmlj,
           Case When asumf2 <> 0 Then Stvj   / asumf2 Else 0 End   as qmvj,
           case When asumf2 <> 0 Then Stvvj  / asumf2 Else 0 End   as qmvvj,
           Case When asumf2 <> 0 Then StFrei / asumf2 Else 0 End   as qmfrei, 
           st3J / 34,00                                            as stpromon, 
           st3J / 34,00 / asumf2                                   as qmpromon,
           case when stlj <> 0   Then StFrei / Cast(Stlj as Dec(31, 15)) / 10,0       
                                 Else 0 End                        as rwlj,
           case when St3j <> 0   Then StFrei / Cast(St3j as Dec(31, 15)) / ".$totmon" 
                                 Else 0 End                        as rw,
           St3J / 34,00 * 9,00 - StFrei as stprod9 
           Case When asumf2 <> 0 
                Then (Cast(St3J as Dec(31, 15)) / 34,00 * 9 - StFrei) / asumf2  
                Else 0 End                                         as qmprod9,    
           asabc,
           asme2
    from xJoin
    where     asidn111 = '1' 
          and asidn132 < '40'
          and (   stlj > 0 or stvj > 0 or stvvj > 0 or Stfrei > 0)
    order by case when asme2 = 'st' then Stprod9 Else qmprod9 end desc
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  7. #19
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    "Wenn der Nenner eines Bruchs eine Dezimal-Zahl ist, wird intern automatisch in Float umgewandelt."
    Wo steht das?
    Es gibt da explizit Dezimalregeln, deshalb kann man auch per Option den Bereich von 31 auf 63 Stellen erweitern.
    Double hat eine maximale Genauigkeit von 17 Stellen, somit würden Dezimal-Ergebnisse verfälscht.
    Wenn bei einer komplexeren Formel Genauigkeit verloren geht, gibts nämlich einen Joblog-Eintrag sowie eine Warnung an das Programm mit einem entsprechenden SQLSTATE.
    Ein expliziter Cast eines Divisors in höhere Genauigkeit verschärft das Problem zusaätzlich.

    https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/db2/rbafzdecarithmetic.htm

    Was wohl korrekt ist:
    Ist ein Operand Double/Float wird der gesamte Ausdruck als Double berechnet.

    Zusätzlich hat ein Cast nichts mit der NULL-Problematik zu tun.
    Die Frage ist lediglich, ob ASUMF2 bereits NULL enthalten kann und ggf. in COALESCE zu packen wäre.

    Was den Konstantenwert im Coalesce angeht, so wird das Ergebnis nach den Rechenregeln automatisch angepasst:
    coalesce(dec(1, 11, 2), 0) => dec(11, 2)
    coalesce(dec(1, 11, 2), 0.000) => dec(12, 3)
    usw.
    Es reicht daher im Allgemeinen die Konstante 0 zu verwenden.

    Natürlich gibt es noch die Integer-Regel:
    Sind alle Operatoren ohne Dezimale, wird eine Integer-Operation durchgeführt.
    Allerdings muss die Ganzzahl auch in einen passenden Integer-Typ castbar sein.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

Similar Threads

  1. Muss mich hier heute ständig neu anmelden !!!
    By Peet in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 16-04-20, 15:18
  2. XML-INTO - ich glaub mich tritt ein Pferd
    By camouflage in forum IBM i Hauptforum
    Antworten: 14
    Letzter Beitrag: 18-02-20, 18:37
  3. Befehl CPYTOIMPF
    By alex61 in forum IBM i Hauptforum
    Antworten: 21
    Letzter Beitrag: 09-09-19, 19:55
  4. Antworten: 8
    Letzter Beitrag: 18-05-16, 15:11
  5. Antworten: 5
    Letzter Beitrag: 11-12-13, 03:27

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •